@vimhead.dev/norn-cli 0.1.0-tip.35568631545.1 → 0.1.0-tip.35570530940.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/assets/README.md CHANGED
@@ -20,8 +20,9 @@ through the CLI from any harness. Agents run on the bundled
20
20
 
21
21
  const summarize = workflow({
22
22
  name: "summarize",
23
- isEntrypoint: true,
24
- instructions: "Summarize staged and unstaged tracked changes relative to HEAD in an absolute repositoryPath. Requires Git and an existing commit; untracked files are excluded. Saves workspace-relative summaryPath and retains the diff log. A nonempty diff is sent to the configured model; an empty diff needs no model call.",
23
+ entrypoint: {
24
+ instructions: "Summarize staged and unstaged tracked changes relative to HEAD in an absolute repositoryPath. Requires Git and an existing commit; untracked files are excluded. Saves workspace-relative summaryPath and retains the diff log. A nonempty diff is sent to the configured model; an empty diff needs no model call.",
25
+ },
25
26
  args: Type.Object({ repositoryPath: Type.String({ minLength: 1 }) }),
26
27
  async execute({ args, paths, commands, logs, agents, run }) {
27
28
  const diff = await commands.run({
@@ -14,8 +14,7 @@ import { Type } from "typebox";
14
14
 
15
15
  export const greet = workflow({
16
16
  name: "greet",
17
- isEntrypoint: true,
18
- instructions: "Return a greeting for the supplied name.",
17
+ entrypoint: { instructions: "Return a greeting for the supplied name." },
19
18
  args: Type.Object({ name: Type.String() }),
20
19
  execute({ args, run }) {
21
20
  return run.complete({ summary: `Hello, ${args.name}!` });
@@ -25,11 +24,11 @@ export const greet = workflow({
25
24
  export default [greet];
26
25
  ```
27
26
 
28
- Supply `name`, `args`, `isEntrypoint`, and `execute` explicitly. Entrypoints need nonempty caller-facing `instructions`; internal steps may omit them. `isEntrypoint` controls default catalogue visibility, not authorization: the CLI can start a known internal workflow ID directly.
27
+ Supply `name`, `args`, `entrypoint`, and `execute` explicitly. Use `entrypoint: { instructions: "..." }` with nonempty caller-facing instructions, or `entrypoint: false` for an internal step. This controls default catalogue visibility, not authorization: the CLI can start a known internal workflow ID directly. Discovery exposes the derived `isEntrypoint` boolean and `instructions` string; internal steps have no caller instructions.
29
28
 
30
29
  Workflow and scope names must be nonempty and cannot contain dots. A standalone workflow's ID is its name; a scoped workflow's ID is `<scope name>.<workflow name>`. Declarations expose the resolved `id`; CLI commands, references, and `run.next` use that exact ID, without implicit scope lookup.
31
30
 
32
- `instructions` describe selection, inputs, effects, and outputs. They are neither a Norn agent system prompt nor a gate decision. Declare args and config with [TypeBox schemas](schemas.md). Workflow inputs must be JSON data; `execute` receives the values after schema defaults and conversions. Public schemas must support `workflows inspect`.
31
+ `entrypoint.instructions` describe selection, inputs, effects, and outputs. They are neither a Norn agent system prompt nor a gate decision. Declare args and config with [TypeBox schemas](schemas.md). Workflow inputs must be JSON data; `execute` receives the values after schema defaults and conversions. Public schemas must support `workflows inspect`.
33
32
 
34
33
  Destructure the properties needed by the step from `execute(context)`. Gate descriptions receive the same inferred context:
35
34
 
@@ -79,7 +78,7 @@ export const reports = workflowScope({
79
78
 
80
79
  export const save = reports.workflow({
81
80
  name: "save",
82
- isEntrypoint: false,
81
+ entrypoint: false,
83
82
  args: Type.Object({ text: Type.String() }),
84
83
  config: Type.Object({ filename: Type.String() }),
85
84
  async execute({ args, config, scope, paths, run }) {
@@ -116,7 +115,7 @@ import { Type } from "typebox";
116
115
 
117
116
  const repeat = workflow({
118
117
  name: "repeat",
119
- isEntrypoint: false,
118
+ entrypoint: false,
120
119
  args: Type.Object({ remaining: Type.Integer() }),
121
120
  execute({ args, run }): WorkflowResult {
122
121
  return args.remaining > 0
@@ -24,8 +24,7 @@ const analysisSchema = Type.Object({
24
24
  const scope = workflowScope({ name: "sourceSummary" });
25
25
  export const draft = scope.workflow({
26
26
  name: "draft",
27
- isEntrypoint: true,
28
- instructions: "Summarize a supplied source, save the draft, and independently assess its support and omissions. Returns workspace-relative draftPath and analysisPath plus an assessment; needs-revision is a completed assessment, not an approved summary.",
27
+ entrypoint: { instructions: "Summarize a supplied source, save the draft, and independently assess its support and omissions. Returns workspace-relative draftPath and analysisPath plus an assessment; needs-revision is a completed assessment, not an approved summary." },
29
28
  args: Type.Object({ source: Type.String({ minLength: 1 }) }),
30
29
  async execute({ args, paths, agents }) {
31
30
  const draft = await agents.prompt({
@@ -47,7 +46,7 @@ export const draft = scope.workflow({
47
46
  });
48
47
  export const analyze = scope.workflow({
49
48
  name: "analyze",
50
- isEntrypoint: false,
49
+ entrypoint: false,
51
50
  args: Type.Object({ draftPath: Type.String() }),
52
51
  async execute({ args, paths, agents, run }) {
53
52
  const savedDraft = Value.Parse(savedDraftSchema, JSON.parse(await readFile(join(paths.workspace, args.draftPath), "utf8")));
@@ -12,7 +12,7 @@ const deliveryArgsSchema = Type.Object({
12
12
  const scope = workflowScope({ name: "greetingConsumer" });
13
13
  export const saveJson = scope.workflow({
14
14
  name: "saveJson",
15
- isEntrypoint: false,
15
+ entrypoint: false,
16
16
  args: deliveryArgsSchema,
17
17
  async execute({ args, paths, run }) {
18
18
  const greeting = await readFile(join(paths.workspace, args.resultPath), "utf8");
@@ -30,7 +30,7 @@ export const saveJson = scope.workflow({
30
30
  });
31
31
  export const saveText = scope.workflow({
32
32
  name: "saveText",
33
- isEntrypoint: false,
33
+ entrypoint: false,
34
34
  args: deliveryArgsSchema,
35
35
  async execute({ args, paths, run }) {
36
36
  const greeting = await readFile(join(paths.workspace, args.resultPath), "utf8");
@@ -11,8 +11,7 @@ export const greetingContributionSchema = Type.Object({
11
11
  const scope = workflowScope({ name: "greetingProducer" });
12
12
  export const write = scope.workflow({
13
13
  name: "write",
14
- isEntrypoint: true,
15
- instructions: "Write a greeting file for name, then invoke the caller-selected next workflow with workspace-relative resultPath and summary. The continuation owns completion; no model or external service is used.",
14
+ entrypoint: { instructions: "Write a greeting file for name, then invoke the caller-selected next workflow with workspace-relative resultPath and summary. The continuation owns completion; no model or external service is used." },
16
15
  args: Type.Object({
17
16
  name: Type.String({ minLength: 1 }),
18
17
  next: workflowRefSchema({ args: greetingContributionSchema }),
@@ -13,8 +13,7 @@ const workerReportSchema = Type.Object({ status: Type.Enum(["acknowledged", "idl
13
13
  const scope = workflowScope({ name: "coordinatingAgents" });
14
14
  export const start = scope.workflow({
15
15
  name: "start",
16
- isEntrypoint: true,
17
- instructions: "Summarize 2–12 supplied notes using two concurrent Norn agents and a shared leased work queue. Checkpoint completed rounds, verify every persisted result and exact source quotation, and return workspace-relative summariesPath for summaries.json. Requires configured Norn agent authentication; modifies only this run's logs and workspace.",
16
+ entrypoint: { instructions: "Summarize 2–12 supplied notes using two concurrent Norn agents and a shared leased work queue. Checkpoint completed rounds, verify every persisted result and exact source quotation, and return workspace-relative summariesPath for summaries.json. Requires configured Norn agent authentication; modifies only this run's logs and workspace." },
18
17
  args: inputSchema,
19
18
  async execute({ args, paths }) {
20
19
  const queue = await openQueue({ workspace: paths.workspace, create: true });
@@ -28,7 +27,7 @@ export const start = scope.workflow({
28
27
  });
29
28
  export const work = scope.workflow({
30
29
  name: "work",
31
- isEntrypoint: false,
30
+ entrypoint: false,
32
31
  args: Type.Object({ ...inputSchema.properties, round: Type.Integer({ minimum: 0, maximum: 12 }) }, { additionalProperties: false }),
33
32
  async execute({ args, paths, agents, run }): Promise<WorkflowResult> {
34
33
  const queue = await openQueue({ workspace: paths.workspace, create: false });
@@ -54,7 +53,7 @@ export const work = scope.workflow({
54
53
  });
55
54
  export const verify = scope.workflow({
56
55
  name: "verify",
57
- isEntrypoint: false,
56
+ entrypoint: false,
58
57
  args: inputSchema,
59
58
  async execute({ args, paths, run }) {
60
59
  const queue = await openQueue({ workspace: paths.workspace, create: false });
@@ -5,8 +5,7 @@ import { Type } from "typebox";
5
5
 
6
6
  export const summarize = workflow({
7
7
  name: "summarize",
8
- isEntrypoint: true,
9
- instructions: "Summarize staged and unstaged tracked changes relative to HEAD in an absolute repositoryPath. Requires Git and an existing commit; untracked files are excluded. Saves workspace-relative summaryPath and retains the diff log. A nonempty diff is sent to the configured model; an empty diff needs no model call.",
8
+ entrypoint: { instructions: "Summarize staged and unstaged tracked changes relative to HEAD in an absolute repositoryPath. Requires Git and an existing commit; untracked files are excluded. Saves workspace-relative summaryPath and retains the diff log. A nonempty diff is sent to the configured model; an empty diff needs no model call." },
10
9
  args: Type.Object({ repositoryPath: Type.String({ minLength: 1 }) }),
11
10
  async execute({ args, paths, commands, logs, agents, run }) {
12
11
  const diff = await commands.run({
@@ -5,8 +5,7 @@ import { Type } from "typebox";
5
5
 
6
6
  export const write = workflow({
7
7
  name: "greet",
8
- isEntrypoint: true,
9
- instructions: "Write a greeting file for the supplied name. Returns the greeting text and its workspace-relative greetingPath; no agent or external service is used.",
8
+ entrypoint: { instructions: "Write a greeting file for the supplied name. Returns the greeting text and its workspace-relative greetingPath; no agent or external service is used." },
10
9
  args: Type.Object({ name: Type.Decode(Type.String({ pattern: "\\S" }), value => value.trim()) }),
11
10
  async execute({ args, paths, run }) {
12
11
  const greeting = `Hello, ${args.name}!`;
@@ -11,8 +11,7 @@ const copyField = { id: "copiedText", schema: Type.String() };
11
11
 
12
12
  export const copy = copyScope.workflow({
13
13
  name: "copy",
14
- isEntrypoint: true,
15
- instructions: "A Norn agent reads explicitly shared source and writes a copy, then a separate workflow verifies exact equality from a workspace SQLite database.",
14
+ entrypoint: { instructions: "A Norn agent reads explicitly shared source and writes a copy, then a separate workflow verifies exact equality from a workspace SQLite database." },
16
15
  args: Type.Object({ source: Type.String({ minLength: 1, maxLength: 500 }) }),
17
16
  async execute({ args, paths, agents }) {
18
17
  const state = await SharedState.open({ path: join(paths.workspace, "state.sqlite"), create: true });
@@ -37,7 +36,7 @@ export const copy = copyScope.workflow({
37
36
  },
38
37
  });
39
38
  export const verify = copyScope.workflow({
40
- name: "verify", isEntrypoint: false, args: Type.Object({}),
39
+ name: "verify", entrypoint: false, args: Type.Object({}),
41
40
  async execute({ paths, run }) {
42
41
  const state = await SharedState.open({ path: join(paths.workspace, "state.sqlite"), create: false });
43
42
  try {
@@ -6,8 +6,7 @@ import { materializeWorkspaceRepository } from "./repository.ts";
6
6
 
7
7
  export const developmentLoopWorkflow = developmentLoopScope.workflow({
8
8
  name: "developmentLoop",
9
- isEntrypoint: true,
10
- instructions: "Plan once, then loop implementation and review in a workspace repository copy. Call this when a repository task should run through planning, implementation, and review.",
9
+ entrypoint: { instructions: "Plan once, then loop implementation and review in a workspace repository copy. Call this when a repository task should run through planning, implementation, and review." },
11
10
  args: developmentLoopArgsSchema,
12
11
  async execute({ args, scope, paths, commands }): Promise<WorkflowResult> {
13
12
  const repositoryPath = await materializeWorkspaceRepository({ commands, paths, repositoryRoot: scope.config.repositoryRoot, baseRef: args.baseRef });
@@ -9,8 +9,7 @@ import { implementationAgentResponseSchema } from "./schema.ts";
9
9
 
10
10
  export const implementationWorkflow = developmentLoopScope.workflow({
11
11
  name: "implementation",
12
- isEntrypoint: false,
13
- instructions: "Apply one implementation pass in the current repository.",
12
+ entrypoint: false,
14
13
  args: implementationArgsSchema,
15
14
  async execute({ args, paths, agents, commands, logs }): Promise<WorkflowResult> {
16
15
  const repositoryPath = resolve(paths.workspace, args.repositoryPath);
@@ -8,8 +8,7 @@ import { planningAgentResponseSchema } from "./schema.ts";
8
8
 
9
9
  export const planningWorkflow = developmentLoopScope.workflow({
10
10
  name: "planning",
11
- isEntrypoint: false,
12
- instructions: "Create an implementation plan for a repository task.",
11
+ entrypoint: false,
13
12
  args: planningArgsSchema,
14
13
  async execute({ args, paths, agents }): Promise<WorkflowResult> {
15
14
  const repositoryPath = resolve(paths.workspace, args.repositoryPath);
@@ -9,8 +9,7 @@ import { reviewAgentResponseSchema } from "./schema.ts";
9
9
 
10
10
  export const reviewWorkflow = developmentLoopScope.workflow({
11
11
  name: "review",
12
- isEntrypoint: false,
13
- instructions: "Review the current repository boundary changes.",
12
+ entrypoint: false,
14
13
  args: reviewArgsSchema,
15
14
  async execute({ args, paths, agents, commands, logs }): Promise<WorkflowResult> {
16
15
  const repositoryPath = resolve(paths.workspace, args.repositoryPath);
@@ -8,8 +8,7 @@ import type { StoredReview } from "../review/schema.ts";
8
8
 
9
9
  export const reviewRouterWorkflow = developmentLoopScope.workflow({
10
10
  name: "reviewRouter",
11
- isEntrypoint: false,
12
- instructions: "Route implementation and review iterations based on the latest review decision.",
11
+ entrypoint: false,
13
12
  gate: {
14
13
  enabled: true,
15
14
  describe: ({ args }) => `Review iteration ${args.iteration}. Confirm or edit the automated decision before continuing. Plan: ${args.planPath}.`,
@@ -1 +1 @@
1
- {"version":"0.1.0-tip.35568631545.1"}
1
+ {"version":"0.1.0-tip.35570530940.1"}
@@ -2,8 +2,8 @@ import type { NornBuildInfo } from "./build-info.ts";
2
2
 
3
3
  export const NORN_GENERATED_BUILD_INFO = {
4
4
  "kind": "npm-registry",
5
- "version": "0.1.0-tip.35568631545.1",
6
- "commit": "f16f4b16ede3d325d56cdbd1f21193b3a3d45d38",
5
+ "version": "0.1.0-tip.35570530940.1",
6
+ "commit": "48ecaf47ae0e82e17970db9465497a4e1ad5ff10",
7
7
  "packageSpec": "@vimhead.dev/norn-cli@tip",
8
8
  "upgrade": {
9
9
  "supported": false,
@@ -105,7 +105,7 @@ export class NornWorkflowRegistry {
105
105
  ].map(({ configuration, scopeId }) => ({ key: configuration.key, scopeId, configSchema: configuration.schema ? inspectSchema(configuration.schema) : null, config: configuration.value }));
106
106
  }
107
107
 
108
- launchableEntries(): NornRegisteredWorkflow[] { return this.sortedEntries().filter(({ workflow }) => workflow.isEntrypoint); }
108
+ launchableEntries(): NornRegisteredWorkflow[] { return this.sortedEntries().filter(({ workflow }) => workflow.entrypoint !== false); }
109
109
  workflowById(workflowId: string): NornAnyWorkflowDeclaration | undefined { return this.entries.get(workflowId)?.workflow; }
110
110
 
111
111
  async describeGate(input: NornWorkflowExecutionInput): Promise<string> {
@@ -189,7 +189,9 @@ function assertGateWorkflow(workflow: NornAnyWorkflowDeclaration): void {
189
189
 
190
190
  function workflowInfo(entry: NornRegisteredWorkflow): NornRegisteredWorkflowInfo {
191
191
  return {
192
- id: entry.workflow.id, instructions: entry.workflow.instructions, isEntrypoint: entry.workflow.isEntrypoint,
192
+ id: entry.workflow.id,
193
+ instructions: entry.workflow.entrypoint === false ? undefined : entry.workflow.entrypoint.instructions,
194
+ isEntrypoint: entry.workflow.entrypoint !== false,
193
195
  source: entry.source,
194
196
  configKey: entry.workflow.id,
195
197
  scope: entry.scopeId ? { id: entry.scopeId } : undefined,
@@ -32,8 +32,7 @@ export type NornWorkflowDeclaration<
32
32
  (args: StaticEncode<ArgsSchema>): NornRunNext;
33
33
  readonly kind: typeof WORKFLOW_DECLARATION_KIND;
34
34
  readonly id: Id;
35
- readonly isEntrypoint: boolean;
36
- readonly instructions?: string;
35
+ readonly entrypoint: NornWorkflowEntrypoint;
37
36
  readonly args: ArgsSchema;
38
37
  readonly gate?: NornWorkflowGate<ArgsSchema> & {
39
38
  describe?(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<string>;
@@ -65,9 +64,7 @@ export type NornWorkflowGate<ArgsSchema extends TSchema> = unknown extends Stati
65
64
  readonly fields?: never;
66
65
  };
67
66
 
68
- type NornWorkflowInstructions =
69
- | { readonly isEntrypoint: true; readonly instructions: string }
70
- | { readonly isEntrypoint: false; readonly instructions?: string };
67
+ export type NornWorkflowEntrypoint = false | { readonly instructions: string };
71
68
 
72
69
  type WorkflowConfig<Schema extends TSchema | undefined> = Schema extends TSchema ? StaticDecode<Schema> : undefined;
73
70
 
@@ -94,13 +91,14 @@ export type NornWorkflowDefinition<
94
91
  Scope extends NornWorkflowScopeInfo | undefined = undefined,
95
92
  > = {
96
93
  readonly name: Name;
94
+ readonly entrypoint: NornWorkflowEntrypoint;
97
95
  readonly args: ArgsSchema;
98
96
  readonly config?: ConfigSchema;
99
97
  readonly gate?: NornWorkflowGate<ArgsSchema> & {
100
98
  describe?(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<string>;
101
99
  };
102
100
  execute(context: NornWorkflowContext<ArgsSchema, ConfigSchema, Scope>): MaybePromise<WorkflowResult>;
103
- } & NornWorkflowInstructions;
101
+ };
104
102
 
105
103
  export type NornWorkflowScopeInfo = {
106
104
  readonly id: string;
@@ -134,8 +132,8 @@ function createWorkflow<Id extends string, ArgsSchema extends TSchema, ConfigSch
134
132
  id,
135
133
  scope,
136
134
  }) as NornWorkflowDeclaration<Id, ArgsSchema, ConfigSchema, Scope>;
137
- if (!isWorkflowDeclaration(result)) throw new Error(`Invalid workflow definition: ${id}`);
138
135
  assertWorkflowMetadata(result);
136
+ if (!isWorkflowDeclaration(result)) throw new Error(`Invalid workflow definition: ${id}`);
139
137
  return result;
140
138
  }
141
139
 
@@ -564,13 +562,12 @@ function assertDeclarationName(name: string): void {
564
562
 
565
563
  export function isWorkflowDeclaration(value: unknown): value is NornAnyWorkflowDeclaration {
566
564
  if (typeof value !== "function") return false;
567
- const candidate = value as { kind?: unknown; id?: unknown; instructions?: unknown; isEntrypoint?: unknown; args?: unknown; execute?: unknown };
565
+ const candidate = value as { kind?: unknown; id?: unknown; entrypoint?: unknown; args?: unknown; execute?: unknown };
568
566
  return (
569
567
  candidate.kind === WORKFLOW_DECLARATION_KIND &&
570
568
  typeof candidate.id === "string" &&
571
569
  candidate.id.length > 0 &&
572
- (candidate.instructions === undefined || typeof candidate.instructions === "string") &&
573
- typeof candidate.isEntrypoint === "boolean" &&
570
+ (candidate.entrypoint === false || (isPlainObject(candidate.entrypoint) && typeof candidate.entrypoint.instructions === "string")) &&
574
571
  Boolean(candidate.args) &&
575
572
  typeof candidate.execute === "function"
576
573
  );
@@ -43,11 +43,11 @@ function assertWorkflowReferenceAnnotations(schema: unknown): void {
43
43
  }
44
44
 
45
45
  export function assertWorkflowMetadata(workflow: NornAnyWorkflowDeclaration): void {
46
- if (workflow.instructions !== undefined && (typeof workflow.instructions !== "string" || workflow.instructions.trim().length === 0)) {
47
- throw new Error(`Workflow instructions must be a nonempty string: ${workflow.id}`);
48
- }
49
- if (workflow.isEntrypoint && workflow.instructions === undefined) {
50
- throw new Error(`Entrypoint workflow requires instructions: ${workflow.id}`);
46
+ const { entrypoint } = workflow;
47
+ if (entrypoint === false) return;
48
+ if (!isPlainObject(entrypoint)) throw new Error(`Workflow entrypoint must be false or an object with instructions: ${workflow.id}`);
49
+ if (typeof entrypoint.instructions !== "string" || entrypoint.instructions.trim().length === 0) {
50
+ throw new Error(`Workflow entrypoint.instructions must be a nonempty string: ${workflow.id}`);
51
51
  }
52
52
  }
53
53
 
@@ -7,7 +7,7 @@ import { expect, expectTypeOf, test } from "vitest";
7
7
 
8
8
  const refs = workflowScope({ name: "refs" });
9
9
  const target = refs.workflow({
10
- name: "finish", isEntrypoint: false, args: Type.Object({ report: Type.String() }),
10
+ name: "finish", entrypoint: false, args: Type.Object({ report: Type.String() }),
11
11
  execute() { throw new Error("A callable must select a transition, not execute it"); },
12
12
  });
13
13
 
@@ -1,7 +1,7 @@
1
1
  export declare const NORN_GENERATED_BUILD_INFO: {
2
2
  readonly kind: "npm-registry";
3
- readonly version: "0.1.0-tip.35568631545.1";
4
- readonly commit: "f16f4b16ede3d325d56cdbd1f21193b3a3d45d38";
3
+ readonly version: "0.1.0-tip.35570530940.1";
4
+ readonly commit: "48ecaf47ae0e82e17970db9465497a4e1ad5ff10";
5
5
  readonly packageSpec: "@vimhead.dev/norn-cli@tip";
6
6
  readonly upgrade: {
7
7
  readonly supported: false;
@@ -1,8 +1,8 @@
1
1
  // src/generated-build-info.ts
2
2
  var NORN_GENERATED_BUILD_INFO = {
3
3
  "kind": "npm-registry",
4
- "version": "0.1.0-tip.35568631545.1",
5
- "commit": "f16f4b16ede3d325d56cdbd1f21193b3a3d45d38",
4
+ "version": "0.1.0-tip.35570530940.1",
5
+ "commit": "48ecaf47ae0e82e17970db9465497a4e1ad5ff10",
6
6
  "packageSpec": "@vimhead.dev/norn-cli@tip",
7
7
  "upgrade": {
8
8
  "supported": false,
@@ -76,7 +76,7 @@ var NornWorkflowRegistry = class {
76
76
  ].map(({ configuration, scopeId }) => ({ key: configuration.key, scopeId, configSchema: configuration.schema ? inspectSchema(configuration.schema) : null, config: configuration.value }));
77
77
  }
78
78
  launchableEntries() {
79
- return this.sortedEntries().filter(({ workflow }) => workflow.isEntrypoint);
79
+ return this.sortedEntries().filter(({ workflow }) => workflow.entrypoint !== false);
80
80
  }
81
81
  workflowById(workflowId) {
82
82
  return this.entries.get(workflowId)?.workflow;
@@ -156,8 +156,8 @@ function assertGateWorkflow(workflow) {
156
156
  function workflowInfo(entry) {
157
157
  return {
158
158
  id: entry.workflow.id,
159
- instructions: entry.workflow.instructions,
160
- isEntrypoint: entry.workflow.isEntrypoint,
159
+ instructions: entry.workflow.entrypoint === false ? void 0 : entry.workflow.entrypoint.instructions,
160
+ isEntrypoint: entry.workflow.entrypoint !== false,
161
161
  source: entry.source,
162
162
  configKey: entry.workflow.id,
163
163
  scope: entry.scopeId ? { id: entry.scopeId } : void 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vimhead.dev/norn-cli",
3
- "version": "0.1.0-tip.35568631545.1",
3
+ "version": "0.1.0-tip.35570530940.1",
4
4
  "description": "Harness-agnostic runtime for agent-driven and code-driven workflows, built primarily for agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "@earendil-works/pi-coding-agent": "0.85.1",
44
44
  "jiti": "^2.7.0",
45
45
  "typebox": "^1.3.34",
46
- "@vimhead.dev/norn": "0.1.0-tip.35568631545.1"
46
+ "@vimhead.dev/norn": "0.1.0-tip.35570530940.1"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "node ../../scripts/build-package.ts"