Skip to content

Commit 71ab8d8

Browse files
feat: TIER-4 daemon protocol port + settings/ModelID fill + aux leaves + public API wiring (#57)
* feat: add daemon protocol enums (TIER-4a) Mirror daemon/schemas/enums.ts from the private monorepo as the first wave of TIER-4 daemon protocol port. Adds 16 enums covering daemon methods, events, notification types, terminal, MCP config source, session search/load state, and connection state. Internal barrel at src/protocol/daemon/index.ts; not yet wired into the public API (src/index.ts). Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * feat: add daemon protocol leaves (TIER-4b) Mirror 10 daemon leaf schemas from the private monorepo as the second wave of TIER-4 daemon protocol port: - bug-report, management, skills, relay, terminal - connection (token, apiKey) - automations (+ AutomationPrivacyLevel) - plugins (preserves RedactedMarketplaceSourceSchema separation) - mcp (clientSecret, OAuth) - settings (daemon-side defaults) Bundled into the TIER-4a branch (PR #57). Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * feat: add daemon protocol root droid.ts (TIER-4c) Mirror daemon/schemas/droid.ts from the private monorepo as the third and final wave of TIER-4 daemon protocol port. Adds ~155 schemas plus the master DaemonRequestSchema discriminated union covering session lifecycle, file ops, search, git/PR, semantic diff, rewind, auth, permissions/askUser, and session notifications. Secrets carried: session init/load tokens, proxy token (verbatim). Private helpers (createResponseSchema, createAckCompatibleResponseSchema) mirrored as non-exported. Bundled into TIER-4a+4b branch (PR #57). Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * feat: fill Settings/ModelID gap; replace TIER-4b inlined schemas Port settings/schema.ts and ModelID enum from the private monorepo so src/protocol/daemon/plugins.ts and src/protocol/daemon/settings.ts can import MarketplaceSourceSchema, GeneralSettingsSchema, SessionDefault- SettingsSchema, SettingsResolutionEventSchema, and ModelID instead of inlining or string-fallback approximations. RedactedMarketplaceSourceSchema remains intentionally distinct from MarketplaceSourceSchema to preserve the credential-leak guard. Bundled into PR #57. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * feat: add 8 aux protocol leaves (TIER-4d) Mirror auxiliary protocol schemas not part of the daemon RPC surface but useful for SDK consumers parsing on-disk artifacts and policy: - automations (HEARTBEAT.md frontmatter) + AutomationPrivacyLevel consolidated to top-level - session-summary (.jsonl session_start event) - session-tools (generic tool execution output) - session-settings-types (z.infer wrappers) - policy (UserModelPolicySchema) - tools (built-in tool input/result schemas + RiskLevel) - updater (BinaryDownloadPlanSchema) - usage (TokenUsageSchema) Bundled into PR #57. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * feat: expose src/protocol/ as public `protocol` namespace Wire src/protocol/ into the public API via: export * as protocol from './protocol/index.js'; Consumers can now access the daemon protocol schemas as: import { protocol } from '@factory/droid-sdk'; protocol.daemon.DaemonRequestSchema protocol.daemon.DaemonInitializeSessionRequestSchema protocol.usage.TokenUsageSchema protocol.FactoryDroidMessageSchema Namespace export deliberately avoids collisions with the legacy flat `src/protocol.ts` exports. Deprecating those is out of scope for this PR. Bundled into PR #57. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * refactor: drop narrowed GeneralSettingsSchema from public surface The monorepo's GeneralSettingsSchema extends ManagedSettingsBaseSchema with ~70 total fields and pulls a large transitive chain of CLI/UI/ policy schemas (CustomModelsSchema, ModelPolicySchema, McpPolicySchema, MissionPolicySchema, NetworkPolicySchema, SandboxSettingsSchema, FactoryRouterRuleSchema, plus a dozen UI enums) that are not part of the daemon wire protocol. The TIER-4d Settings/ModelID gap fill exposed a 7-field subset under the same name. Exporting a misnamed subset is misleading: callers parsing real settings.json blobs would silently lose 63 fields. Remove GeneralSettingsSchema and the GeneralSettings type from the public surface. The daemon settings RPCs that needed specific field shapes now inline them directly from the monorepo source verbatim. Bundled into PR #57. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> * fix: port GeneralSettingsSchema and ManagedSettingsBaseSchema verbatim Reverses the previous unacceptable narrowing/inlining. The full GeneralSettingsSchema (extends ManagedSettingsBaseSchema, ~70 fields total) is now mirrored verbatim from the monorepo source into a new src/protocol/general-settings.ts module, along with every transitive dependency the closure requires: - 6 new enums (DiffMode, SoundFocusMode, TodoDisplayMode, SubagentSoundMode, LogoAnimationMode, ToolResultDisplay) added verbatim to src/protocol/enums.ts - 4 router-rule constants added verbatim to src/protocol/constants.ts - ModelPolicy, McpPolicy, MissionPolicy, Network/Sandbox/Marketplace/ FactoryRouterRule/StatusLine helper schemas ported verbatim - ManagedSettingsBaseSchema exported (upstream declares it `const`; visibility raised to allow `.extend(...)` across module boundaries — documented in-file) src/protocol/daemon/settings.ts restored to use GeneralSettingsSchema.shape.X exactly as upstream daemon/schemas/ settings.ts does. The previous private GeneralSettingsShape const workaround is removed. Bundled into PR #57. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --------- Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
1 parent ff53ac3 commit 71ab8d8

38 files changed

Lines changed: 5658 additions & 0 deletions

src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ export type {
1616
PermissionHandler,
1717
} from './protocol.js';
1818

19+
// Namespace export for the source-of-truth protocol schemas under src/protocol/.
20+
// Exposed as a namespace to avoid colliding with the flat exports above from
21+
// the legacy `./protocol.js` file. Consumers access these as
22+
// `protocol.DaemonRequestSchema`, `protocol.daemon.…`, `protocol.usage.…`, etc.
23+
export * as protocol from './protocol/index.js';
24+
1925
export { DroidClient } from './client.js';
2026
export type {
2127
ClientAskUserHandler,

src/protocol/automations-enums.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/** Named schedule cadences */
2+
export enum AutomationScheduleCadence {
3+
Daily = 'daily',
4+
Weekly = 'weekly',
5+
Monthly = 'monthly',
6+
}
7+
8+
/** Types of validation issues */
9+
export enum AutomationValidationIssueType {
10+
MissingFile = 'missing_file',
11+
InvalidFrontmatter = 'invalid_frontmatter',
12+
InvalidSchedule = 'invalid_schedule',
13+
ParseError = 'parse_error',
14+
}
15+
16+
// =============================================================================
17+
// Control-plane enums
18+
// =============================================================================
19+
20+
/**
21+
* Control-plane error codes.
22+
*
23+
* These codes enable deterministic error handling across CLI/desktop surfaces.
24+
*/
25+
export enum AutomationErrorCode {
26+
/** Automation with the given ID was not found */
27+
NotFound = 'AUTOMATION_NOT_FOUND',
28+
/** Automation already exists with the given ID */
29+
AlreadyExists = 'AUTOMATION_ALREADY_EXISTS',
30+
/** Invalid automation ID format */
31+
InvalidId = 'INVALID_AUTOMATION_ID',
32+
/** Invalid configuration (e.g., invalid schedule) */
33+
InvalidConfig = 'INVALID_AUTOMATION_CONFIG',
34+
/** Automation is already in the requested state */
35+
AlreadyInState = 'ALREADY_IN_STATE',
36+
/** A run is already in progress for this automation */
37+
RunInProgress = 'RUN_IN_PROGRESS',
38+
/** Heartbeat execution failed */
39+
ExecutionFailed = 'EXECUTION_FAILED',
40+
/** General internal error */
41+
InternalError = 'INTERNAL_ERROR',
42+
}
43+
44+
/** Privacy level for an automation */
45+
export enum AutomationPrivacyLevel {
46+
/** Only visible to the creator */
47+
Private = 'private',
48+
/** Visible to all members of the organization */
49+
Organization = 'organization',
50+
}

src/protocol/automations.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { z } from 'zod';
2+
3+
import { AutomationPrivacyLevel } from './automations-enums.js';
4+
5+
export const AutomationCreatedBySchema = z.object({
6+
name: z.string(),
7+
email: z.string().optional(),
8+
avatarUrl: z.string().optional(),
9+
});
10+
11+
export type AutomationCreatedBy = z.infer<typeof AutomationCreatedBySchema>;
12+
13+
/**
14+
* Schema for the on-disk YAML metadata in HEARTBEAT.md frontmatter.
15+
*
16+
* This is the flat representation stored between `---` delimiters.
17+
* Differs from AutomationConfig in that `schedule` is a plain string
18+
* (e.g. "daily", "0 9 * * 1-5") rather than the runtime
19+
* `{ cadence: string }` shape.
20+
*/
21+
export const AutomationsHeartbeatSchema = z.object({
22+
id: z.string().uuid().optional(),
23+
name: z.string(),
24+
description: z.string().optional(),
25+
schedule: z.string(),
26+
model: z.string().optional(),
27+
tags: z.array(z.string()).optional(),
28+
paused: z.boolean().optional(),
29+
privacyLevel: z.nativeEnum(AutomationPrivacyLevel).optional(),
30+
createdBy: AutomationCreatedBySchema.optional(),
31+
forkedFrom: z.string().optional(),
32+
});
33+
34+
export type AutomationsHeartbeat = z.infer<typeof AutomationsHeartbeatSchema>;

src/protocol/constants.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,28 @@ export const FACTORY_PROTOCOL_VERSION = '1.62.0' as const;
1515

1616
export const JSONRPC_VERSION = '2.0' as const;
1717

18+
/**
19+
* Sentinel ModelID value for the Factory routing model. Faithful copy of
20+
* packages/common/src/llm/constants.ts.
21+
*/
22+
export const FACTORY_ROUTER_MODEL_ID = 'factory-router' as const;
23+
24+
/**
25+
* Sentinel value used by CompactionModelSchema to mean "use the session's
26+
* current model for compaction". Faithful copy of
27+
* packages/common/src/settings/constants.ts.
28+
*/
29+
export const CURRENT_COMPACTION_MODEL = 'current-model';
30+
31+
// Faithful copy of packages/common/src/settings/constants.ts router-rule
32+
// guardrails. Used by ManagedSettingsBaseSchema and FactoryRouterRuleSchema.
33+
34+
/** Sized comparably to a trimmed user message in the classifier context budget. */
35+
export const FACTORY_ROUTER_GUIDANCE_MAX_LENGTH = 2000;
36+
export const FACTORY_ROUTER_RULES_MAX_COUNT = 20;
37+
export const FACTORY_ROUTER_RULE_WHEN_MAX_LENGTH = 300;
38+
export const FACTORY_ROUTER_RULE_GUIDANCE_MAX_LENGTH = 600;
39+
1840
const seconds = (value: number) => value * 1_000;
1941
const minutes = (value: number) => seconds(value * 60);
2042
const hours = (value: number) => minutes(value * 60);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Re-export from the hoisted top-level automations enums module so daemon
2+
// consumers continue to import `AutomationPrivacyLevel` from this path while
3+
// the canonical definition lives at `src/protocol/automations-enums.ts`.
4+
export * from '../automations-enums.js';

0 commit comments

Comments
 (0)