@autonomos/core 0.3.3 → 0.4.0
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/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +14 -6
- package/dist/index.mjs.map +1 -1
- package/dist/workflows/protocol-crystallize.md +10 -7
- package/dist/workflows/protocol-issue.md +37 -0
- package/dist/workflows/protocol-reconcile.md +32 -0
- package/dist/workflows/protocol-session.md +16 -15
- package/dist/workflows/protocol-task.md +7 -4
- package/dist/workflows/protocol-workflows.test.ts +151 -22
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
* Agent Protocol Specification Version (Independent of Package versions)
|
|
6
6
|
* This refers to the schema and behavioral contract version.
|
|
7
7
|
*/
|
|
8
|
-
declare const PROTOCOL_VERSION = "0.
|
|
8
|
+
declare const PROTOCOL_VERSION = "0.4.0-alpha";
|
|
9
9
|
/**
|
|
10
10
|
* Directory name for Autonomos configuration
|
|
11
11
|
*/
|
|
@@ -355,11 +355,11 @@ declare function parseManifest(content: string): Manifest;
|
|
|
355
355
|
* - No duplication between PROTOCOL.md and workflows.
|
|
356
356
|
* - Short enough that an LLM can re-scan it mid-session without cost.
|
|
357
357
|
*/
|
|
358
|
-
declare const PROTOCOL_TEMPLATE = "# AUTONOMOS PROTOCOL (v0.
|
|
358
|
+
declare const PROTOCOL_TEMPLATE = "# AUTONOMOS PROTOCOL (v0.4.0-alpha)\n\n> This file defines the project's AI workflow contract. The workflows execute it. Do not duplicate workflow steps here.\n\n## Quick Reference\n\n| Action | How |\n|---|---|\n| Start a session | Read the `/session` workflow |\n| Start a task | Read the `/task` workflow |\n| Triage a problem or proposal | Read the optional `/issue` workflow |\n| Audit accumulated drift | Read the `/reconcile` workflow |\n| End a session | Read the `/crystallize` workflow |\n| Get context | Read root `AGENT.md`, then only the selected scope's ancestor chain |\n| Resolve objective | Explicit user request first; otherwise resume `[/]` or pick highest-priority `[ ]` |\n| Log session work | Create `.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md` |\n\n## File Map\n\n| File | Location | Role |\n|---|---|---|\n| `AGENT.md` | Root + any subdirectory | Durable guidance for its directory scope |\n| `TASKS.md` | `.autonomos/TASKS.md` | Single source of truth for task state |\n| `ISSUES.md` | `.autonomos/ISSUES.md` | Optional problem, proposal, and question intake |\n| `worklogs/` | `.autonomos/worklogs/` | Historical session evidence, not current guidance |\n| `PROTOCOL.md` | `.autonomos/PROTOCOL.md` | This file \u2014 read-only reference |\n| `manifest.json` | `.autonomos/manifest.json` | Protocol version metadata |\n\n## AGENT.md Format Rules\n\nStore only stable guidance that will affect different future tasks. Keep transient evidence in worklogs and operational explanations in component documentation. Use the narrowest applicable `AGENT.md`; consolidate or replace obsolete entries instead of appending history.\n\n**Root `AGENT.md`** \u2014 Must use the structured template (frontmatter + sections: Context, Workflow, Stack, Key Directories, Constraints).\n\n**Local `AGENT.md`** (in any subdirectory) \u2014 Free format. One line is enough if it is clear. What matters: the next session can use it. Example:\n\n```markdown\n# AGENT: packages/core\n- Stack: TypeScript, Vitest, tsdown\n- Conventions: exports via src/index.ts, tests co-located (*.test.ts)\n- Constraint: template changes require workflow test updates\n```\n\n## Issue and Task Rules\n\nIssues describe evidence, impact, and a desired outcome without choosing implementation. Tasks describe an accepted intervention and completion criteria. Use optional `ISSUES.md` only when triage is useful; direct, clear changes may become tasks immediately. Link accepted issues and their tasks both ways.\n\n## Task Format\n\n`- [Status] **[ID]** Title \\`Priority\\` \\`Complexity\\``\n\n| Status | Priority | Complexity |\n|---|---|---|\n| `[ ]` Todo | `\uD83D\uDD34 Critical` | `S` Small |\n| `[/]` In Progress | `\uD83D\uDFE0 High` | `M` Medium |\n| `[x]` Done | `\uD83D\uDD35 Medium` | `L` Large |\n| `[!]` Blocked | `\u26AA Low` | `XL` Huge |\n\n## Metadata Rules\n\n- **Language:** English unless AGENT.md says otherwise.\n- **Tone:** Technical, concise, fact-based.\n- **Continuity:** Refer to previous work as \"we\" or \"the project\".\n";
|
|
359
359
|
/**
|
|
360
360
|
* @deprecated Use PROTOCOL_TEMPLATE instead
|
|
361
361
|
*/
|
|
362
|
-
declare const PROTOCOL_TEMPLATE_V2026_1 = "# AUTONOMOS PROTOCOL (v0.
|
|
362
|
+
declare const PROTOCOL_TEMPLATE_V2026_1 = "# AUTONOMOS PROTOCOL (v0.4.0-alpha)\n\n> This file defines the project's AI workflow contract. The workflows execute it. Do not duplicate workflow steps here.\n\n## Quick Reference\n\n| Action | How |\n|---|---|\n| Start a session | Read the `/session` workflow |\n| Start a task | Read the `/task` workflow |\n| Triage a problem or proposal | Read the optional `/issue` workflow |\n| Audit accumulated drift | Read the `/reconcile` workflow |\n| End a session | Read the `/crystallize` workflow |\n| Get context | Read root `AGENT.md`, then only the selected scope's ancestor chain |\n| Resolve objective | Explicit user request first; otherwise resume `[/]` or pick highest-priority `[ ]` |\n| Log session work | Create `.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md` |\n\n## File Map\n\n| File | Location | Role |\n|---|---|---|\n| `AGENT.md` | Root + any subdirectory | Durable guidance for its directory scope |\n| `TASKS.md` | `.autonomos/TASKS.md` | Single source of truth for task state |\n| `ISSUES.md` | `.autonomos/ISSUES.md` | Optional problem, proposal, and question intake |\n| `worklogs/` | `.autonomos/worklogs/` | Historical session evidence, not current guidance |\n| `PROTOCOL.md` | `.autonomos/PROTOCOL.md` | This file \u2014 read-only reference |\n| `manifest.json` | `.autonomos/manifest.json` | Protocol version metadata |\n\n## AGENT.md Format Rules\n\nStore only stable guidance that will affect different future tasks. Keep transient evidence in worklogs and operational explanations in component documentation. Use the narrowest applicable `AGENT.md`; consolidate or replace obsolete entries instead of appending history.\n\n**Root `AGENT.md`** \u2014 Must use the structured template (frontmatter + sections: Context, Workflow, Stack, Key Directories, Constraints).\n\n**Local `AGENT.md`** (in any subdirectory) \u2014 Free format. One line is enough if it is clear. What matters: the next session can use it. Example:\n\n```markdown\n# AGENT: packages/core\n- Stack: TypeScript, Vitest, tsdown\n- Conventions: exports via src/index.ts, tests co-located (*.test.ts)\n- Constraint: template changes require workflow test updates\n```\n\n## Issue and Task Rules\n\nIssues describe evidence, impact, and a desired outcome without choosing implementation. Tasks describe an accepted intervention and completion criteria. Use optional `ISSUES.md` only when triage is useful; direct, clear changes may become tasks immediately. Link accepted issues and their tasks both ways.\n\n## Task Format\n\n`- [Status] **[ID]** Title \\`Priority\\` \\`Complexity\\``\n\n| Status | Priority | Complexity |\n|---|---|---|\n| `[ ]` Todo | `\uD83D\uDD34 Critical` | `S` Small |\n| `[/]` In Progress | `\uD83D\uDFE0 High` | `M` Medium |\n| `[x]` Done | `\uD83D\uDD35 Medium` | `L` Large |\n| `[!]` Blocked | `\u26AA Low` | `XL` Huge |\n\n## Metadata Rules\n\n- **Language:** English unless AGENT.md says otherwise.\n- **Tone:** Technical, concise, fact-based.\n- **Continuity:** Refer to previous work as \"we\" or \"the project\".\n";
|
|
363
363
|
//#endregion
|
|
364
364
|
//#region src/templates/tasks.d.ts
|
|
365
365
|
/**
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/constants.ts","../src/schemas/harness-codes.ts","../src/schemas/manifest.ts","../src/types.ts","../src/templates/agent.ts","../src/templates/manifest.ts","../src/templates/protocol.ts","../src/templates/tasks.ts","../src/templates/worklog.ts","../src/parsers/agent-finder.ts","../src/parsers/agent-parser.ts","../src/parsers/project-root.ts","../src/parsers/task-parser.ts","../src/harness-codes.ts"],"mappings":";;;;;;AAIA;cAAa,gBAAA;;;AAAgB;cAKhB,aAAA;;;;cAKA,aAAA;AAAb;;;AAAA,cAKa,aAAA;AALa;AAK1B;;AAL0B,cAUb,UAAA;;AALa;AAK1B;cAKa,UAAA;;;AALU;cAUV,YAAA;;;;;AA9Bb;;;;AAA6B;AAK7B;;;;AAA0B;cCKb,eAAA,EAAe,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmBf,aAAA,EAAa,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cASb,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAInB,SAAA,GAAY,CAAA,CAAE,KAAK,QAAQ,eAAA;AAAA,KAC3B,OAAA,GAAU,CAAA,CAAE,KAAK,QAAQ,aAAA;AAAA,KACzB,YAAA,GAAe,CAAA,CAAE,KAAK,QAAQ,kBAAA;;;;;AD5C1C;cECa,cAAA,EAAc,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAOf,QAAA,GAAW,CAAA,CAAE,KAAK,QAAQ,cAAA;;;;;;KCT1B,QAAA;;;;KAKA,UAAA;AHCZ;;;AAAA,KGIY,UAAA;AHJc;AAK1B;;AAL0B,UGST,IAAA;EACb,EAAA;EACA,KAAA;EACA,QAAA,EAAU,QAAA;EACV,UAAA,EAAY,UAAA;EACZ,MAAA,EAAQ,UAAA;EACR,WAAA;AAAA;AHAJ;;;AAAA,UGMiB,WAAA;EACb,IAAA;EACA,WAAA;EACA,KAAA;EACA,WAAA,GAAc,MAAM;AAAA;AAAA,UAGP,YAAA;EACb,KAAA;EACA,OAAO;AAAA;AAAA,UAGM,YAAA;EACb,KAAA;EACA,WAAA;EACA,QAAA,EAAU,YAAA;EACV,QAAA,GAAW,MAAM;AAAA;AAAA,cAGR,UAAA,EAAY,QAAQ;AAAA,cACpB,YAAA,EAAc,UAAU;;;;;;AH9CrC;iBIAgB,qBAAA,CAAsB,WAA+B;;;AJAxC;AAK7B;;iBImCgB,0BAAA,CAA2B,OAAe;;AJnChC;AAK1B;cI0Ca,cAAA;;;AJ1Ca;cI+Cb,oBAAA;;;;;AJzDb;iBKEgB,cAAA,CAAe,UAAA,WAAqB,QAAQ;;;ALF/B;iBKeb,uBAAA,CAAwB,QAAkB,EAAR,QAAQ;;;;iBAO1C,aAAA,CAAc,OAAA,WAAkB,QAAQ;;;;;;ALtBxD;;;;AAA6B;AAK7B;cMEa,iBAAA;;;ANFa;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/constants.ts","../src/schemas/harness-codes.ts","../src/schemas/manifest.ts","../src/types.ts","../src/templates/agent.ts","../src/templates/manifest.ts","../src/templates/protocol.ts","../src/templates/tasks.ts","../src/templates/worklog.ts","../src/parsers/agent-finder.ts","../src/parsers/agent-parser.ts","../src/parsers/project-root.ts","../src/parsers/task-parser.ts","../src/harness-codes.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{z as e}from"zod";import{existsSync as t,statSync as n}from"node:fs";import{dirname as r,isAbsolute as i,join as a,relative as o,resolve as s,sep as c}from"node:path";import l from"js-yaml";const u=`0.
|
|
1
|
+
import{z as e}from"zod";import{existsSync as t,statSync as n}from"node:fs";import{dirname as r,isAbsolute as i,join as a,relative as o,resolve as s,sep as c}from"node:path";import l from"js-yaml";const u=`0.4.0-alpha`,d=`.autonomos`,f=`manifest.json`,p=`PROTOCOL.md`,m=`TASKS.md`,h=`AGENT.md`,g=`worklogs`,_=e.object({workflowsDir:e.string().optional(),targetDir:e.string().optional(),skillsDir:e.string().optional(),commandsDir:e.string().optional(),globalTargetDir:e.string().optional(),fileExtension:e.string()}).refine(e=>!!e.workflowsDir||!!e.targetDir||!!e.skillsDir,{message:"At least one of `workflowsDir`, `targetDir`, or `skillsDir` must be defined"}),v=e.object({name:e.string().min(1),preferred:e.boolean(),installer:_}),y=e.object({platforms:e.record(e.string(),v)}),b=e.object({protocolVersion:e.string().describe(`Version of the Agent Protocol specification`),cliVersion:e.string().describe(`Version of the CLI that last updated this project`),initializedAt:e.string().datetime().describe(`ISO timestamp of project initialization`),lastUpdated:e.string().datetime().describe(`ISO timestamp of last protocol update`)}),x=[`🔴 Critical`,`🟠 High`,`🔵 Medium`,`⚪ Low`],S=[`S`,`M`,`L`,`XL`];function C(e=`Project`){return`---
|
|
2
2
|
name: "${e}"
|
|
3
3
|
type: "project"
|
|
4
4
|
status: "active"
|
|
@@ -45,24 +45,28 @@ status: "active"
|
|
|
45
45
|
|---|---|
|
|
46
46
|
| Start a session | Read the \`/session\` workflow |
|
|
47
47
|
| Start a task | Read the \`/task\` workflow |
|
|
48
|
+
| Triage a problem or proposal | Read the optional \`/issue\` workflow |
|
|
49
|
+
| Audit accumulated drift | Read the \`/reconcile\` workflow |
|
|
48
50
|
| End a session | Read the \`/crystallize\` workflow |
|
|
49
|
-
| Get context | Read \`AGENT.md
|
|
50
|
-
|
|
|
51
|
-
| Pick next task | Open \`.autonomos/TASKS.md\`, pick highest priority not \`[x]\` |
|
|
51
|
+
| Get context | Read root \`AGENT.md\`, then only the selected scope's ancestor chain |
|
|
52
|
+
| Resolve objective | Explicit user request first; otherwise resume \`[/]\` or pick highest-priority \`[ ]\` |
|
|
52
53
|
| Log session work | Create \`.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md\` |
|
|
53
54
|
|
|
54
55
|
## File Map
|
|
55
56
|
|
|
56
57
|
| File | Location | Role |
|
|
57
58
|
|---|---|---|
|
|
58
|
-
| \`AGENT.md\` | Root + any subdirectory |
|
|
59
|
+
| \`AGENT.md\` | Root + any subdirectory | Durable guidance for its directory scope |
|
|
59
60
|
| \`TASKS.md\` | \`.autonomos/TASKS.md\` | Single source of truth for task state |
|
|
60
|
-
| \`
|
|
61
|
+
| \`ISSUES.md\` | \`.autonomos/ISSUES.md\` | Optional problem, proposal, and question intake |
|
|
62
|
+
| \`worklogs/\` | \`.autonomos/worklogs/\` | Historical session evidence, not current guidance |
|
|
61
63
|
| \`PROTOCOL.md\` | \`.autonomos/PROTOCOL.md\` | This file — read-only reference |
|
|
62
64
|
| \`manifest.json\` | \`.autonomos/manifest.json\` | Protocol version metadata |
|
|
63
65
|
|
|
64
66
|
## AGENT.md Format Rules
|
|
65
67
|
|
|
68
|
+
Store only stable guidance that will affect different future tasks. Keep transient evidence in worklogs and operational explanations in component documentation. Use the narrowest applicable \`AGENT.md\`; consolidate or replace obsolete entries instead of appending history.
|
|
69
|
+
|
|
66
70
|
**Root \`AGENT.md\`** — Must use the structured template (frontmatter + sections: Context, Workflow, Stack, Key Directories, Constraints).
|
|
67
71
|
|
|
68
72
|
**Local \`AGENT.md\`** (in any subdirectory) — Free format. One line is enough if it is clear. What matters: the next session can use it. Example:
|
|
@@ -74,6 +78,10 @@ status: "active"
|
|
|
74
78
|
- Constraint: template changes require workflow test updates
|
|
75
79
|
\`\`\`
|
|
76
80
|
|
|
81
|
+
## Issue and Task Rules
|
|
82
|
+
|
|
83
|
+
Issues describe evidence, impact, and a desired outcome without choosing implementation. Tasks describe an accepted intervention and completion criteria. Use optional \`ISSUES.md\` only when triage is useful; direct, clear changes may become tasks immediately. Link accepted issues and their tasks both ways.
|
|
84
|
+
|
|
77
85
|
## Task Format
|
|
78
86
|
|
|
79
87
|
\`- [Status] **[ID]** Title \\\`Priority\\\` \\\`Complexity\\\`\`
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["harnessCodesData"],"sources":["../src/constants.ts","../src/schemas/harness-codes.ts","../src/schemas/manifest.ts","../src/types.ts","../src/templates/agent.ts","../src/templates/manifest.ts","../src/templates/protocol.ts","../src/templates/tasks.ts","../src/templates/worklog.ts","../src/parsers/agent-finder.ts","../src/parsers/agent-parser.ts","../src/parsers/project-root.ts","../src/parsers/task-parser.ts","../src/data/harness-codes.json","../src/harness-codes.ts"],"sourcesContent":["/**\n * Agent Protocol Specification Version (Independent of Package versions)\n * This refers to the schema and behavioral contract version.\n */\nexport const PROTOCOL_VERSION = '0.3.1-alpha'\n\n/**\n * Directory name for Autonomos configuration\n */\nexport const AUTONOMOS_DIR = '.autonomos'\n\n/**\n * Manifest filename\n */\nexport const MANIFEST_FILE = 'manifest.json'\n\n/**\n * Protocol filename\n */\nexport const PROTOCOL_FILE = 'PROTOCOL.md'\n\n/**\n * Tasks filename\n */\nexport const TASKS_FILE = 'TASKS.md'\n\n/**\n * Agent context filename (at project root)\n */\nexport const AGENT_FILE = 'AGENT.md'\n\n/**\n * Worklogs directory name\n */\nexport const WORKLOGS_DIR = 'worklogs'\n","import { z } from 'zod'\n\n/**\n * Installer configuration for a single harness.\n *\n * At least one of `workflowsDir`, `targetDir`, or `skillsDir` must be defined.\n *\n * - `workflowsDir`: Where session.md, task.md, crystallize.md are written.\n * Preferred field — used by most harnesses.\n * - `targetDir`: Single directory (legacy, like Cline's .clinerules/workflows/).\n * - `skillsDir`: Skills directory (legacy, for harnesses that don't distinguish\n * skills from workflows).\n * - `commandsDir`: Additional commands directory (optional).\n */\nexport const InstallerSchema = z\n .object({\n workflowsDir: z.string().optional(),\n targetDir: z.string().optional(),\n skillsDir: z.string().optional(),\n commandsDir: z.string().optional(),\n globalTargetDir: z.string().optional(),\n fileExtension: z.string(),\n })\n .refine(\n data => Boolean(data.workflowsDir) || Boolean(data.targetDir) || Boolean(data.skillsDir),\n {\n message: 'At least one of `workflowsDir`, `targetDir`, or `skillsDir` must be defined',\n }\n )\n\n/**\n * A single harness entry.\n */\nexport const HarnessSchema = z.object({\n name: z.string().min(1),\n preferred: z.boolean(),\n installer: InstallerSchema,\n})\n\n/**\n * Root schema for the harness-codes configuration file.\n */\nexport const HarnessCodesSchema = z.object({\n platforms: z.record(z.string(), HarnessSchema),\n})\n\nexport type Installer = z.infer<typeof InstallerSchema>\nexport type Harness = z.infer<typeof HarnessSchema>\nexport type HarnessCodes = z.infer<typeof HarnessCodesSchema>\n","import { z } from 'zod'\n\n/**\n * Manifest Schema for .autonomos/manifest.json\n */\nexport const ManifestSchema = z.object({\n protocolVersion: z.string().describe('Version of the Agent Protocol specification'),\n cliVersion: z.string().describe('Version of the CLI that last updated this project'),\n initializedAt: z.string().datetime().describe('ISO timestamp of project initialization'),\n lastUpdated: z.string().datetime().describe('ISO timestamp of last protocol update'),\n})\n\nexport type Manifest = z.infer<typeof ManifestSchema>\n","/**\n * Priority levels for tasks\n */\nexport type Priority = '🔴 Critical' | '🟠 High' | '🔵 Medium' | '⚪ Low'\n\n/**\n * Complexity estimates for tasks\n */\nexport type Complexity = 'S' | 'M' | 'L' | 'XL'\n\n/**\n * Task status markers\n */\nexport type TaskStatus = 'TODO' | 'IN_PROGRESS' | 'DONE' | 'BLOCKED'\n\n/**\n * Task entity parsed from TASKS.md\n */\nexport interface Task {\n id: string\n title: string\n priority: Priority\n complexity: Complexity\n status: TaskStatus\n worklogPath?: string\n}\n\n/**\n * Agent configuration parsed from AGENT.md\n */\nexport interface AgentConfig {\n name: string\n description?: string\n stack: string[]\n preferences?: Record<string, any>\n}\n\nexport interface AgentSection {\n title: string\n content: string\n}\n\nexport interface AgentContext {\n title: string\n description?: string\n sections: AgentSection[]\n metadata?: Record<string, any>\n}\n\nexport const PRIORITIES: Priority[] = ['🔴 Critical', '🟠 High', '🔵 Medium', '⚪ Low']\nexport const COMPLEXITIES: Complexity[] = ['S', 'M', 'L', 'XL']\n","/**\n * Template for AGENT.md - The context anchor at project root\n * @param projectName - Name of the project to personalize the template\n */\nexport function generateAgentTemplate(projectName: string = 'Project'): string {\n return `---\nname: \"${projectName}\"\ntype: \"project\"\nstatus: \"active\"\n---\n# AGENT CONTEXT: ${projectName}\n\n## 🧠 Context & Objectives\n\n*Describe what this project does and its main goals.*\n\n## ⚙️ Workflow & Preferences\n\n- **Commits:** Conventional Commits\n- **Language:** English\n\n## 🏗 Stack & Architecture\n\n- **Tech:** *(List frameworks, libraries)*\n- **Patterns:** *(Architecture patterns used)*\n\n## 📁 Key Directories\n\n| Path | Description |\n|------|-------------|\n| \\`src/\\` | Source code |\n| \\`.autonomos/\\` | Agent Protocol files |\n\n## ⚠️ Known Constraints\n\n*List any technical debts, missing features, or external limitations.*\n`\n}\n\n/**\n * Generate a minimal local AGENT.md for subdirectories.\n * Free format by design — low friction encourages creation.\n * @param dirName - Name of the directory\n */\nexport function generateLocalAgentTemplate(dirName: string): string {\n return `# AGENT: ${dirName}\n\n- **Stack:** *(frameworks, libs specific to this module)*\n- **Conventions:** *(naming, exports, test patterns)*\n- **Constraints:** *(known issues, tech debt)*\n`\n}\n\n/**\n * Default root AGENT.md template\n */\nexport const AGENT_TEMPLATE = generateAgentTemplate()\n\n/**\n * Default local AGENT.md template\n */\nexport const LOCAL_AGENT_TEMPLATE = generateLocalAgentTemplate('module')\n","import { PROTOCOL_VERSION } from '../constants'\nimport { ManifestSchema, type Manifest } from '../schemas/manifest'\n\n/**\n * Creates a new manifest object with current timestamps\n */\nexport function createManifest(cliVersion: string): Manifest {\n const now = new Date().toISOString()\n return {\n protocolVersion: PROTOCOL_VERSION,\n cliVersion,\n initializedAt: now,\n lastUpdated: now,\n }\n}\n\n/**\n * Generates the manifest.json content as a formatted string\n */\nexport function generateManifestContent(manifest: Manifest): string {\n return JSON.stringify(manifest, null, 4) + '\\n'\n}\n\n/**\n * Parses manifest.json content into a Manifest object with validation\n */\nexport function parseManifest(content: string): Manifest {\n const data = JSON.parse(content)\n return ManifestSchema.parse(data)\n}\n","import { PROTOCOL_VERSION } from '../constants'\n\n/**\n * The Protocol kernel template — v0.3\n *\n * Design principles (v0.3):\n * - PROTOCOL.md is a compact REFERENCE, not an executable workflow.\n * - All step-by-step instructions live in the 3 workflow files.\n * - No duplication between PROTOCOL.md and workflows.\n * - Short enough that an LLM can re-scan it mid-session without cost.\n */\nexport const PROTOCOL_TEMPLATE = `# AUTONOMOS PROTOCOL (v${PROTOCOL_VERSION})\n\n> This file defines the project's AI workflow contract. The workflows execute it. Do not duplicate workflow steps here.\n\n## Quick Reference\n\n| Action | How |\n|---|---|\n| Start a session | Read the \\`/session\\` workflow |\n| Start a task | Read the \\`/task\\` workflow |\n| End a session | Read the \\`/crystallize\\` workflow |\n| Get context | Read \\`AGENT.md\\` (root → local) |\n| Find all AGENT.md | \\`find . -name AGENT.md -not -path '*/node_modules/*'\\` |\n| Pick next task | Open \\`.autonomos/TASKS.md\\`, pick highest priority not \\`[x]\\` |\n| Log session work | Create \\`.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md\\` |\n\n## File Map\n\n| File | Location | Role |\n|---|---|---|\n| \\`AGENT.md\\` | Root + any subdirectory | Fractal knowledge base (context, preferences, stack) |\n| \\`TASKS.md\\` | \\`.autonomos/TASKS.md\\` | Single source of truth for task state |\n| \\`worklogs/\\` | \\`.autonomos/worklogs/\\` | Session history (one file per session) |\n| \\`PROTOCOL.md\\` | \\`.autonomos/PROTOCOL.md\\` | This file — read-only reference |\n| \\`manifest.json\\` | \\`.autonomos/manifest.json\\` | Protocol version metadata |\n\n## AGENT.md Format Rules\n\n**Root \\`AGENT.md\\`** — Must use the structured template (frontmatter + sections: Context, Workflow, Stack, Key Directories, Constraints).\n\n**Local \\`AGENT.md\\`** (in any subdirectory) — Free format. One line is enough if it is clear. What matters: the next session can use it. Example:\n\n\\`\\`\\`markdown\n# AGENT: packages/core\n- Stack: TypeScript, Vitest, tsdown\n- Conventions: exports via src/index.ts, tests co-located (*.test.ts)\n- Constraint: template changes require workflow test updates\n\\`\\`\\`\n\n## Task Format\n\n\\`- [Status] **[ID]** Title \\\\\\`Priority\\\\\\` \\\\\\`Complexity\\\\\\`\\`\n\n| Status | Priority | Complexity |\n|---|---|---|\n| \\`[ ]\\` Todo | \\`🔴 Critical\\` | \\`S\\` Small |\n| \\`[/]\\` In Progress | \\`🟠 High\\` | \\`M\\` Medium |\n| \\`[x]\\` Done | \\`🔵 Medium\\` | \\`L\\` Large |\n| \\`[!]\\` Blocked | \\`⚪ Low\\` | \\`XL\\` Huge |\n\n## Metadata Rules\n\n- **Language:** English unless AGENT.md says otherwise.\n- **Tone:** Technical, concise, fact-based.\n- **Continuity:** Refer to previous work as \"we\" or \"the project\".\n`\n\n/**\n * @deprecated Use PROTOCOL_TEMPLATE instead\n */\nexport const PROTOCOL_TEMPLATE_V2026_1 = PROTOCOL_TEMPLATE\n","/**\n * Template for TASKS.md - The task registry\n */\nexport const TASKS_TEMPLATE = `# PROJECT TASKS & ROADMAP\n\n> **LEGEND**\n> **Priority:** [🔴 Critical] [🟠 High] [🔵 Medium] [⚪ Low]\n> **Complexity:** [S] Small (1h), [M] Medium (4h), [L] Large (1-2 days), [XL] Huge (Planning req.)\n> **Status:** [ ] Todo, [/] In Progress, [x] Done, [!] Blocked\n\n## 🚀 Active Sprint\n\n- [ ] **[INIT-01]** Review project context and structure \\`Priority: 🔵\\` \\`Complexity: S\\`\n\n## 🔮 Backlog\n\n*(Add future tasks here)*\n`\n","import type { TaskStatus } from '../types'\n\ninterface WorklogOptions {\n taskId: string\n taskName: string\n date?: string\n status: 'Complete' | 'Partial' | 'Blocked'\n description: string\n filesModified: string[]\n decisions: string[]\n challenges: string[]\n nextSteps: string[]\n}\n\n/**\n * Generate a Worklog markdown content\n */\nexport function generateWorklogContent(options: WorklogOptions): string {\n const date = options.date ?? new Date().toISOString().split('T')[0]\n\n return `# WORKLOG: [${options.taskId}] ${options.taskName}\n**Date:** ${date}\n**Agent Status:** [${options.status}]\n\n## 📝 Description\n${options.description}\n\n## 🛠 Technical Details\n- **Files Modified:**\n${options.filesModified.map(f => ` - ${f}`).join('\\n')}\n- **Key Decisions:**\n${options.decisions.map(d => ` - ${d}`).join('\\n')}\n- **Challenges:**\n${options.challenges.map(c => ` - ${c}`).join('\\n')}\n\n## ⏭ Next Steps / Context for Successor\n${options.nextSteps.map(s => `- ${s}`).join('\\n')}\n`\n}\n\n/**\n * Common status mapping for worklogs\n */\nexport function mapTaskStatusToWorklogStatus(\n status: TaskStatus\n): 'Complete' | 'Partial' | 'Blocked' {\n switch (status) {\n case 'DONE':\n return 'Complete'\n case 'BLOCKED':\n return 'Blocked'\n default:\n return 'Partial'\n }\n}\n","import { existsSync, statSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\n\nimport { AGENT_FILE } from '../constants'\n\n/**\n * Result of an ancestor lookup: a single AGENT.md entry that exists on the\n * path between a target file or directory and the project root.\n */\nexport interface AncestorAgent {\n /** Absolute path to the directory containing the AGENT.md */\n dir: string\n /** Absolute path to the AGENT.md file */\n path: string\n /** Path of the directory relative to the project root */\n relativeDir: string\n}\n\n/**\n * Return the ordered list of AGENT.md files that exist on the path from a\n * target file or directory up to the project root. The order is root-first,\n * then each intermediate directory, then the target directory itself.\n *\n * Non-existent AGENT.md files are silently skipped (the chain can have gaps).\n *\n * @param target - The absolute or project-relative path to a file or directory.\n * @param projectRoot - The absolute path of the project root (where the root\n * AGENT.md lives). Defaults to the current working directory.\n *\n * @example\n * findAncestorAgents('/proj/apps/web/components/ui/button.tsx', '/proj')\n * // Returns, in order:\n * // - { dir: '/proj', path: '/proj/AGENT.md' }\n * // - { dir: '/proj/apps/web', path: '/proj/apps/web/AGENT.md' }\n * // (apps/, components/ skipped because they have no AGENT.md)\n * // (button.tsx itself is a file, so its parent dir is the last one checked)\n */\nexport function findAncestorAgents(\n target: string,\n projectRoot: string = process.cwd()\n): AncestorAgent[] {\n const absRoot = resolve(projectRoot)\n const absTarget = resolveAgainstRoot(target, absRoot)\n\n // Validate that the target lives within the project root\n const relToRoot = relative(absRoot, absTarget)\n if (relToRoot.startsWith('..') || isAbsolute(relToRoot)) {\n throw new Error(\n `Target \"${target}\" is outside the project root \"${absRoot}\". ` +\n `findAncestorAgents only handles paths within the project.`\n )\n }\n\n // Collect every directory from the target up to the root, in root-first order.\n // For a file target, we only look at the directory chain (not the file itself).\n // For a directory target, the directory itself is included as the last entry.\n const targetDir = isDirectory(absTarget) ? absTarget : dirname(absTarget)\n const dirs = collectAncestorDirs(targetDir, absRoot)\n\n const result: AncestorAgent[] = []\n for (const dir of dirs) {\n const agentPath = join(dir, AGENT_FILE)\n if (existsSync(agentPath)) {\n result.push({\n dir,\n path: agentPath,\n relativeDir: relativeDir(dir, absRoot),\n })\n }\n }\n\n return result\n}\n\n/**\n * Resolve a target path against the project root. Accepts absolute paths\n * (returned as-is) and project-relative paths (joined with the root).\n */\nfunction resolveAgainstRoot(target: string, absRoot: string): string {\n if (isAbsolute(target)) return target\n return join(absRoot, target)\n}\n\n/**\n * Return the directory chain from a starting directory up to (and including)\n * the project root, in root-first order. The chain is computed by walking\n * the relative path segments from the starting dir back to the root.\n */\nfunction collectAncestorDirs(startDir: string, absRoot: string): string[] {\n const rel = relative(absRoot, startDir)\n if (rel === '' || rel === '.') {\n return [absRoot]\n }\n\n const segments = rel.split(sep).filter(s => s !== '' && s !== '.')\n const chain: string[] = [absRoot]\n let acc = absRoot\n for (const seg of segments) {\n acc = join(acc, seg)\n chain.push(acc)\n }\n return chain\n}\n\n/**\n * Compute the directory's path relative to the project root, in a form\n * suitable for display. The root itself is rendered as \".\".\n */\nfunction relativeDir(dir: string, absRoot: string): string {\n const rel = relative(absRoot, dir)\n return rel === '' ? '.' : rel\n}\n\nfunction isDirectory(p: string): boolean {\n try {\n return statSync(p).isDirectory()\n } catch {\n return false\n }\n}\n","import yaml from 'js-yaml'\nimport type { AgentContext, AgentSection } from '../types'\n\nexport class AgentParser {\n /**\n * Parse an AGENT.md content into a structured AgentContext\n */\n static parse(markdown: string): AgentContext {\n let content = markdown\n let metadata: Record<string, any> = {}\n\n // Parse Frontmatter\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/\n const match = markdown.match(frontmatterRegex)\n if (match) {\n try {\n metadata = yaml.load(match[1] as string) as Record<string, any>\n content = markdown.slice(match[0].length).trim()\n } catch (e) {\n console.error('Failed to parse Agent frontmatter:', e)\n }\n }\n\n const lines = content.split(/\\r?\\n/)\n const sections: AgentSection[] = []\n let title = metadata.name ?? 'Unknown Agent'\n let currentSection: AgentSection | null = null\n let currentContent: string[] = []\n\n for (const line of lines) {\n // Parse Title (Only if not already set by frontmatter)\n if (line.startsWith('# ') && !metadata.name) {\n const rawTitle = line.replace('# ', '').trim()\n // Handle \"AGENT CONTEXT: [Name]\" format\n if (rawTitle.toUpperCase().startsWith('AGENT CONTEXT:')) {\n title = rawTitle\n .slice(14)\n .replace(/^[:\\s-]+/, '')\n .trim()\n } else {\n title = rawTitle\n }\n continue\n }\n\n // Parse Sections\n if (line.startsWith('## ')) {\n // Save previous section\n if (currentSection) {\n currentSection.content = currentContent.join('\\n').trim()\n sections.push(currentSection)\n }\n\n currentSection = {\n title: line.replace('## ', '').trim(),\n content: '',\n }\n currentContent = []\n continue\n }\n\n // Collect content\n if (currentSection) {\n currentContent.push(line)\n }\n }\n\n // Save last section\n if (currentSection) {\n currentSection.content = currentContent.join('\\n').trim()\n sections.push(currentSection)\n }\n\n return {\n title,\n sections,\n metadata,\n }\n }\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\n\nimport { AUTONOMOS_DIR } from '../constants'\n\n/**\n * Markers that identify the root of an Autonomos / git project.\n *\n * `.autonomos/` is a strong signal: if it exists, the project has already\n * been initialized with the protocol and the directory containing it is,\n * by definition, the project root.\n *\n * `.git/` is a weaker signal: it only tells us the directory is inside a\n * git working tree. We still stop at the first `.git/` we see, which is\n * good enough for the common monorepo case (the monorepo root contains\n * the `.git/`, package subdirectories do not).\n */\nconst PROJECT_MARKERS = [AUTONOMOS_DIR, '.git'] as const\n\n/**\n * Find the directory that owns this project by walking up from `startDir`\n * until we find a directory containing `.autonomos/` or `.git/`.\n *\n * Returns `null` if no such directory exists before we reach the\n * filesystem root.\n *\n * Notes on behavior:\n * - The search stops at the first directory that contains any of the\n * markers. For monorepos this is the monorepo root, not the package\n * directory the caller is sitting in.\n * - A directory containing `.git/` is preferred over walking further up:\n * this prevents leaking into a parent repository in nested-worktree\n * setups. Callers that need the absolute git toplevel can run\n * `git rev-parse --show-toplevel` themselves after this returns.\n *\n * @param startDir - Absolute path to start the search from.\n */\nexport function findProjectRoot(startDir: string): string | null {\n if (!startDir) return null\n const start = resolve(startDir)\n let current = start\n\n while (true) {\n if (PROJECT_MARKERS.some(marker => existsSync(join(current, marker)))) {\n return current\n }\n const parent = dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n\n/**\n * Check whether two absolute paths refer to the same directory.\n *\n * Resolves `.` / `..` segments before comparing, so `/a/b` and\n * `/a/b/./` are considered the same.\n */\nexport function isSamePath(a: string, b: string): boolean {\n if (!a || !b) return false\n return resolve(a) === resolve(b)\n}\n\n/**\n * Render a path relative to another path, with one guarantee that the\n * default `path.relative` doesn't give us: we never return a value that\n * starts with `..`. If `target` is not under `base`, we return the\n * absolute resolved path of `target` so the caller can still show a\n * useful location.\n */\nexport function displayRelative(target: string, base: string): string {\n const rel = relative(base, target)\n if (rel === '' || rel === '.') return '.'\n if (rel.startsWith(`..${sep}`) || rel === '..' || isAbsolute(rel)) {\n return resolve(target)\n }\n return rel\n}\n","import type { Complexity, Priority, Task, TaskStatus } from '../types'\n\nexport class TaskParser {\n static parse(markdown: string): Task[] {\n const tasks: Task[] = []\n const lines = markdown.split(/\\r?\\n/)\n const taskRegex = /- \\[([ x/!])\\] \\*\\*\\[(.+)\\]\\*\\* (.+) `Priority: (.+)` `Complexity: (.+)`/\n\n for (const line of lines) {\n const match = line.match(taskRegex)\n if (match) {\n const [, statusChar = ' ', id = '', title = '', priority = '', complexity = ''] =\n match\n tasks.push({\n id,\n title: title.trim(),\n priority: priority as Priority,\n complexity: complexity as Complexity,\n status: this.mapStatus(statusChar),\n })\n }\n }\n return tasks\n }\n\n private static mapStatus(char: string): TaskStatus {\n switch (char) {\n case ' ':\n return 'TODO'\n case '/':\n return 'IN_PROGRESS'\n case 'x':\n return 'DONE'\n case '!':\n return 'BLOCKED'\n default:\n return 'TODO'\n }\n }\n}\n","","import harnessCodesData from './data/harness-codes.json' with { type: 'json' }\nimport {\n HarnessCodesSchema,\n type Harness,\n type HarnessCodes,\n type Installer,\n} from './schemas/harness-codes'\n\n/**\n * Validated, in-memory representation of the harness codes config.\n * Loaded once at module init, validated via Zod.\n */\nconst codes: HarnessCodes = HarnessCodesSchema.parse(harnessCodesData)\n\n/**\n * Get a single harness entry by its id.\n * Throws if the id is unknown.\n */\nexport function getHarness(id: string): Harness {\n const entry = codes.platforms[id]\n if (!entry) {\n const known = Object.keys(codes.platforms).join(', ')\n throw new Error(`Unknown harness: \"${id}\". Known harnesses: ${known}`)\n }\n return entry\n}\n\n/**\n * List all configured harnesses, as an array of {id, harness} pairs.\n * Stable order: insertion order of the JSON object.\n */\nexport function listHarnesses(): Array<{ id: string; harness: Harness }> {\n return Object.entries(codes.platforms).map(([id, harness]) => ({ id, harness }))\n}\n\n/**\n * Get the list of preferred harnesses (shown as recommended options).\n */\nexport function listPreferredHarnesses(): Array<{ id: string; harness: Harness }> {\n return listHarnesses().filter(({ harness }) => harness.preferred)\n}\n\n/**\n * A resolved target directory where workflow files will be written.\n * One per unique path, with the list of harness ids that share it.\n */\nexport interface ResolvedTarget {\n /** Absolute or project-relative path to the directory */\n path: string\n /** File extension to use (e.g. \".md\", \".agent.md\") */\n fileExtension: string\n /** Ids of the harnesses that will read from this directory */\n usedBy: string[]\n}\n\n/**\n * Resolve the unique target directories for a set of harness ids.\n *\n * Harnesses that share the same `skillsDir` (e.g. Codex, OpenCode, KiloCode\n * all use `.agents/skills/`) are deduplicated: the directory appears once\n * in the output, with all the harness ids listed in `usedBy`.\n *\n * The `path` is returned relative to the project root (caller is responsible\n * for joining with the project cwd).\n */\nexport function resolveTargets(harnessIds: string[], cwd: string = '.'): ResolvedTarget[] {\n const map = new Map<string, ResolvedTarget>()\n\n for (const id of harnessIds) {\n const { installer } = getHarness(id)\n collectFromInstaller(map, installer, id, cwd)\n }\n\n return Array.from(map.values())\n}\n\nfunction collectFromInstaller(\n map: Map<string, ResolvedTarget>,\n installer: Installer,\n harnessId: string,\n cwd: string\n): void {\n const ext = installer.fileExtension\n if (installer.workflowsDir) {\n addTarget(map, joinPath(cwd, installer.workflowsDir), ext, harnessId)\n } else if (installer.targetDir) {\n addTarget(map, joinPath(cwd, installer.targetDir), ext, harnessId)\n } else if (installer.skillsDir) {\n addTarget(map, joinPath(cwd, installer.skillsDir), ext, harnessId)\n }\n if (installer.commandsDir) {\n addTarget(map, joinPath(cwd, installer.commandsDir), ext, harnessId)\n }\n}\n\nfunction addTarget(\n map: Map<string, ResolvedTarget>,\n path: string,\n fileExtension: string,\n harnessId: string\n): void {\n const existing = map.get(path)\n if (existing) {\n if (!existing.usedBy.includes(harnessId)) {\n existing.usedBy.push(harnessId)\n }\n } else {\n map.set(path, { path, fileExtension, usedBy: [harnessId] })\n }\n}\n\nfunction joinPath(a: string, b: string): string {\n if (a === '.' || a === '') return b\n if (b.startsWith('/')) return `${a}${b}`\n return `${a}/${b}`\n}\n\n/**\n * Get the raw (validated) codes object, for advanced use cases.\n * Most callers should use the higher-level helpers above.\n */\nexport function getRawHarnessCodes(): HarnessCodes {\n return codes\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["harnessCodesData"],"sources":["../src/constants.ts","../src/schemas/harness-codes.ts","../src/schemas/manifest.ts","../src/types.ts","../src/templates/agent.ts","../src/templates/manifest.ts","../src/templates/protocol.ts","../src/templates/tasks.ts","../src/templates/worklog.ts","../src/parsers/agent-finder.ts","../src/parsers/agent-parser.ts","../src/parsers/project-root.ts","../src/parsers/task-parser.ts","../src/data/harness-codes.json","../src/harness-codes.ts"],"sourcesContent":["/**\n * Agent Protocol Specification Version (Independent of Package versions)\n * This refers to the schema and behavioral contract version.\n */\nexport const PROTOCOL_VERSION = '0.4.0-alpha'\n\n/**\n * Directory name for Autonomos configuration\n */\nexport const AUTONOMOS_DIR = '.autonomos'\n\n/**\n * Manifest filename\n */\nexport const MANIFEST_FILE = 'manifest.json'\n\n/**\n * Protocol filename\n */\nexport const PROTOCOL_FILE = 'PROTOCOL.md'\n\n/**\n * Tasks filename\n */\nexport const TASKS_FILE = 'TASKS.md'\n\n/**\n * Agent context filename (at project root)\n */\nexport const AGENT_FILE = 'AGENT.md'\n\n/**\n * Worklogs directory name\n */\nexport const WORKLOGS_DIR = 'worklogs'\n","import { z } from 'zod'\n\n/**\n * Installer configuration for a single harness.\n *\n * At least one of `workflowsDir`, `targetDir`, or `skillsDir` must be defined.\n *\n * - `workflowsDir`: Where session.md, task.md, crystallize.md are written.\n * Preferred field — used by most harnesses.\n * - `targetDir`: Single directory (legacy, like Cline's .clinerules/workflows/).\n * - `skillsDir`: Skills directory (legacy, for harnesses that don't distinguish\n * skills from workflows).\n * - `commandsDir`: Additional commands directory (optional).\n */\nexport const InstallerSchema = z\n .object({\n workflowsDir: z.string().optional(),\n targetDir: z.string().optional(),\n skillsDir: z.string().optional(),\n commandsDir: z.string().optional(),\n globalTargetDir: z.string().optional(),\n fileExtension: z.string(),\n })\n .refine(\n data => Boolean(data.workflowsDir) || Boolean(data.targetDir) || Boolean(data.skillsDir),\n {\n message: 'At least one of `workflowsDir`, `targetDir`, or `skillsDir` must be defined',\n }\n )\n\n/**\n * A single harness entry.\n */\nexport const HarnessSchema = z.object({\n name: z.string().min(1),\n preferred: z.boolean(),\n installer: InstallerSchema,\n})\n\n/**\n * Root schema for the harness-codes configuration file.\n */\nexport const HarnessCodesSchema = z.object({\n platforms: z.record(z.string(), HarnessSchema),\n})\n\nexport type Installer = z.infer<typeof InstallerSchema>\nexport type Harness = z.infer<typeof HarnessSchema>\nexport type HarnessCodes = z.infer<typeof HarnessCodesSchema>\n","import { z } from 'zod'\n\n/**\n * Manifest Schema for .autonomos/manifest.json\n */\nexport const ManifestSchema = z.object({\n protocolVersion: z.string().describe('Version of the Agent Protocol specification'),\n cliVersion: z.string().describe('Version of the CLI that last updated this project'),\n initializedAt: z.string().datetime().describe('ISO timestamp of project initialization'),\n lastUpdated: z.string().datetime().describe('ISO timestamp of last protocol update'),\n})\n\nexport type Manifest = z.infer<typeof ManifestSchema>\n","/**\n * Priority levels for tasks\n */\nexport type Priority = '🔴 Critical' | '🟠 High' | '🔵 Medium' | '⚪ Low'\n\n/**\n * Complexity estimates for tasks\n */\nexport type Complexity = 'S' | 'M' | 'L' | 'XL'\n\n/**\n * Task status markers\n */\nexport type TaskStatus = 'TODO' | 'IN_PROGRESS' | 'DONE' | 'BLOCKED'\n\n/**\n * Task entity parsed from TASKS.md\n */\nexport interface Task {\n id: string\n title: string\n priority: Priority\n complexity: Complexity\n status: TaskStatus\n worklogPath?: string\n}\n\n/**\n * Agent configuration parsed from AGENT.md\n */\nexport interface AgentConfig {\n name: string\n description?: string\n stack: string[]\n preferences?: Record<string, any>\n}\n\nexport interface AgentSection {\n title: string\n content: string\n}\n\nexport interface AgentContext {\n title: string\n description?: string\n sections: AgentSection[]\n metadata?: Record<string, any>\n}\n\nexport const PRIORITIES: Priority[] = ['🔴 Critical', '🟠 High', '🔵 Medium', '⚪ Low']\nexport const COMPLEXITIES: Complexity[] = ['S', 'M', 'L', 'XL']\n","/**\n * Template for AGENT.md - The context anchor at project root\n * @param projectName - Name of the project to personalize the template\n */\nexport function generateAgentTemplate(projectName: string = 'Project'): string {\n return `---\nname: \"${projectName}\"\ntype: \"project\"\nstatus: \"active\"\n---\n# AGENT CONTEXT: ${projectName}\n\n## 🧠 Context & Objectives\n\n*Describe what this project does and its main goals.*\n\n## ⚙️ Workflow & Preferences\n\n- **Commits:** Conventional Commits\n- **Language:** English\n\n## 🏗 Stack & Architecture\n\n- **Tech:** *(List frameworks, libraries)*\n- **Patterns:** *(Architecture patterns used)*\n\n## 📁 Key Directories\n\n| Path | Description |\n|------|-------------|\n| \\`src/\\` | Source code |\n| \\`.autonomos/\\` | Agent Protocol files |\n\n## ⚠️ Known Constraints\n\n*List any technical debts, missing features, or external limitations.*\n`\n}\n\n/**\n * Generate a minimal local AGENT.md for subdirectories.\n * Free format by design — low friction encourages creation.\n * @param dirName - Name of the directory\n */\nexport function generateLocalAgentTemplate(dirName: string): string {\n return `# AGENT: ${dirName}\n\n- **Stack:** *(frameworks, libs specific to this module)*\n- **Conventions:** *(naming, exports, test patterns)*\n- **Constraints:** *(known issues, tech debt)*\n`\n}\n\n/**\n * Default root AGENT.md template\n */\nexport const AGENT_TEMPLATE = generateAgentTemplate()\n\n/**\n * Default local AGENT.md template\n */\nexport const LOCAL_AGENT_TEMPLATE = generateLocalAgentTemplate('module')\n","import { PROTOCOL_VERSION } from '../constants'\nimport { ManifestSchema, type Manifest } from '../schemas/manifest'\n\n/**\n * Creates a new manifest object with current timestamps\n */\nexport function createManifest(cliVersion: string): Manifest {\n const now = new Date().toISOString()\n return {\n protocolVersion: PROTOCOL_VERSION,\n cliVersion,\n initializedAt: now,\n lastUpdated: now,\n }\n}\n\n/**\n * Generates the manifest.json content as a formatted string\n */\nexport function generateManifestContent(manifest: Manifest): string {\n return JSON.stringify(manifest, null, 4) + '\\n'\n}\n\n/**\n * Parses manifest.json content into a Manifest object with validation\n */\nexport function parseManifest(content: string): Manifest {\n const data = JSON.parse(content)\n return ManifestSchema.parse(data)\n}\n","import { PROTOCOL_VERSION } from '../constants'\n\n/**\n * The Protocol kernel template — v0.3\n *\n * Design principles (v0.3):\n * - PROTOCOL.md is a compact REFERENCE, not an executable workflow.\n * - All step-by-step instructions live in the 3 workflow files.\n * - No duplication between PROTOCOL.md and workflows.\n * - Short enough that an LLM can re-scan it mid-session without cost.\n */\nexport const PROTOCOL_TEMPLATE = `# AUTONOMOS PROTOCOL (v${PROTOCOL_VERSION})\n\n> This file defines the project's AI workflow contract. The workflows execute it. Do not duplicate workflow steps here.\n\n## Quick Reference\n\n| Action | How |\n|---|---|\n| Start a session | Read the \\`/session\\` workflow |\n| Start a task | Read the \\`/task\\` workflow |\n| Triage a problem or proposal | Read the optional \\`/issue\\` workflow |\n| Audit accumulated drift | Read the \\`/reconcile\\` workflow |\n| End a session | Read the \\`/crystallize\\` workflow |\n| Get context | Read root \\`AGENT.md\\`, then only the selected scope's ancestor chain |\n| Resolve objective | Explicit user request first; otherwise resume \\`[/]\\` or pick highest-priority \\`[ ]\\` |\n| Log session work | Create \\`.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md\\` |\n\n## File Map\n\n| File | Location | Role |\n|---|---|---|\n| \\`AGENT.md\\` | Root + any subdirectory | Durable guidance for its directory scope |\n| \\`TASKS.md\\` | \\`.autonomos/TASKS.md\\` | Single source of truth for task state |\n| \\`ISSUES.md\\` | \\`.autonomos/ISSUES.md\\` | Optional problem, proposal, and question intake |\n| \\`worklogs/\\` | \\`.autonomos/worklogs/\\` | Historical session evidence, not current guidance |\n| \\`PROTOCOL.md\\` | \\`.autonomos/PROTOCOL.md\\` | This file — read-only reference |\n| \\`manifest.json\\` | \\`.autonomos/manifest.json\\` | Protocol version metadata |\n\n## AGENT.md Format Rules\n\nStore only stable guidance that will affect different future tasks. Keep transient evidence in worklogs and operational explanations in component documentation. Use the narrowest applicable \\`AGENT.md\\`; consolidate or replace obsolete entries instead of appending history.\n\n**Root \\`AGENT.md\\`** — Must use the structured template (frontmatter + sections: Context, Workflow, Stack, Key Directories, Constraints).\n\n**Local \\`AGENT.md\\`** (in any subdirectory) — Free format. One line is enough if it is clear. What matters: the next session can use it. Example:\n\n\\`\\`\\`markdown\n# AGENT: packages/core\n- Stack: TypeScript, Vitest, tsdown\n- Conventions: exports via src/index.ts, tests co-located (*.test.ts)\n- Constraint: template changes require workflow test updates\n\\`\\`\\`\n\n## Issue and Task Rules\n\nIssues describe evidence, impact, and a desired outcome without choosing implementation. Tasks describe an accepted intervention and completion criteria. Use optional \\`ISSUES.md\\` only when triage is useful; direct, clear changes may become tasks immediately. Link accepted issues and their tasks both ways.\n\n## Task Format\n\n\\`- [Status] **[ID]** Title \\\\\\`Priority\\\\\\` \\\\\\`Complexity\\\\\\`\\`\n\n| Status | Priority | Complexity |\n|---|---|---|\n| \\`[ ]\\` Todo | \\`🔴 Critical\\` | \\`S\\` Small |\n| \\`[/]\\` In Progress | \\`🟠 High\\` | \\`M\\` Medium |\n| \\`[x]\\` Done | \\`🔵 Medium\\` | \\`L\\` Large |\n| \\`[!]\\` Blocked | \\`⚪ Low\\` | \\`XL\\` Huge |\n\n## Metadata Rules\n\n- **Language:** English unless AGENT.md says otherwise.\n- **Tone:** Technical, concise, fact-based.\n- **Continuity:** Refer to previous work as \"we\" or \"the project\".\n`\n\n/**\n * @deprecated Use PROTOCOL_TEMPLATE instead\n */\nexport const PROTOCOL_TEMPLATE_V2026_1 = PROTOCOL_TEMPLATE\n","/**\n * Template for TASKS.md - The task registry\n */\nexport const TASKS_TEMPLATE = `# PROJECT TASKS & ROADMAP\n\n> **LEGEND**\n> **Priority:** [🔴 Critical] [🟠 High] [🔵 Medium] [⚪ Low]\n> **Complexity:** [S] Small (1h), [M] Medium (4h), [L] Large (1-2 days), [XL] Huge (Planning req.)\n> **Status:** [ ] Todo, [/] In Progress, [x] Done, [!] Blocked\n\n## 🚀 Active Sprint\n\n- [ ] **[INIT-01]** Review project context and structure \\`Priority: 🔵\\` \\`Complexity: S\\`\n\n## 🔮 Backlog\n\n*(Add future tasks here)*\n`\n","import type { TaskStatus } from '../types'\n\ninterface WorklogOptions {\n taskId: string\n taskName: string\n date?: string\n status: 'Complete' | 'Partial' | 'Blocked'\n description: string\n filesModified: string[]\n decisions: string[]\n challenges: string[]\n nextSteps: string[]\n}\n\n/**\n * Generate a Worklog markdown content\n */\nexport function generateWorklogContent(options: WorklogOptions): string {\n const date = options.date ?? new Date().toISOString().split('T')[0]\n\n return `# WORKLOG: [${options.taskId}] ${options.taskName}\n**Date:** ${date}\n**Agent Status:** [${options.status}]\n\n## 📝 Description\n${options.description}\n\n## 🛠 Technical Details\n- **Files Modified:**\n${options.filesModified.map(f => ` - ${f}`).join('\\n')}\n- **Key Decisions:**\n${options.decisions.map(d => ` - ${d}`).join('\\n')}\n- **Challenges:**\n${options.challenges.map(c => ` - ${c}`).join('\\n')}\n\n## ⏭ Next Steps / Context for Successor\n${options.nextSteps.map(s => `- ${s}`).join('\\n')}\n`\n}\n\n/**\n * Common status mapping for worklogs\n */\nexport function mapTaskStatusToWorklogStatus(\n status: TaskStatus\n): 'Complete' | 'Partial' | 'Blocked' {\n switch (status) {\n case 'DONE':\n return 'Complete'\n case 'BLOCKED':\n return 'Blocked'\n default:\n return 'Partial'\n }\n}\n","import { existsSync, statSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\n\nimport { AGENT_FILE } from '../constants'\n\n/**\n * Result of an ancestor lookup: a single AGENT.md entry that exists on the\n * path between a target file or directory and the project root.\n */\nexport interface AncestorAgent {\n /** Absolute path to the directory containing the AGENT.md */\n dir: string\n /** Absolute path to the AGENT.md file */\n path: string\n /** Path of the directory relative to the project root */\n relativeDir: string\n}\n\n/**\n * Return the ordered list of AGENT.md files that exist on the path from a\n * target file or directory up to the project root. The order is root-first,\n * then each intermediate directory, then the target directory itself.\n *\n * Non-existent AGENT.md files are silently skipped (the chain can have gaps).\n *\n * @param target - The absolute or project-relative path to a file or directory.\n * @param projectRoot - The absolute path of the project root (where the root\n * AGENT.md lives). Defaults to the current working directory.\n *\n * @example\n * findAncestorAgents('/proj/apps/web/components/ui/button.tsx', '/proj')\n * // Returns, in order:\n * // - { dir: '/proj', path: '/proj/AGENT.md' }\n * // - { dir: '/proj/apps/web', path: '/proj/apps/web/AGENT.md' }\n * // (apps/, components/ skipped because they have no AGENT.md)\n * // (button.tsx itself is a file, so its parent dir is the last one checked)\n */\nexport function findAncestorAgents(\n target: string,\n projectRoot: string = process.cwd()\n): AncestorAgent[] {\n const absRoot = resolve(projectRoot)\n const absTarget = resolveAgainstRoot(target, absRoot)\n\n // Validate that the target lives within the project root\n const relToRoot = relative(absRoot, absTarget)\n if (relToRoot.startsWith('..') || isAbsolute(relToRoot)) {\n throw new Error(\n `Target \"${target}\" is outside the project root \"${absRoot}\". ` +\n `findAncestorAgents only handles paths within the project.`\n )\n }\n\n // Collect every directory from the target up to the root, in root-first order.\n // For a file target, we only look at the directory chain (not the file itself).\n // For a directory target, the directory itself is included as the last entry.\n const targetDir = isDirectory(absTarget) ? absTarget : dirname(absTarget)\n const dirs = collectAncestorDirs(targetDir, absRoot)\n\n const result: AncestorAgent[] = []\n for (const dir of dirs) {\n const agentPath = join(dir, AGENT_FILE)\n if (existsSync(agentPath)) {\n result.push({\n dir,\n path: agentPath,\n relativeDir: relativeDir(dir, absRoot),\n })\n }\n }\n\n return result\n}\n\n/**\n * Resolve a target path against the project root. Accepts absolute paths\n * (returned as-is) and project-relative paths (joined with the root).\n */\nfunction resolveAgainstRoot(target: string, absRoot: string): string {\n if (isAbsolute(target)) return target\n return join(absRoot, target)\n}\n\n/**\n * Return the directory chain from a starting directory up to (and including)\n * the project root, in root-first order. The chain is computed by walking\n * the relative path segments from the starting dir back to the root.\n */\nfunction collectAncestorDirs(startDir: string, absRoot: string): string[] {\n const rel = relative(absRoot, startDir)\n if (rel === '' || rel === '.') {\n return [absRoot]\n }\n\n const segments = rel.split(sep).filter(s => s !== '' && s !== '.')\n const chain: string[] = [absRoot]\n let acc = absRoot\n for (const seg of segments) {\n acc = join(acc, seg)\n chain.push(acc)\n }\n return chain\n}\n\n/**\n * Compute the directory's path relative to the project root, in a form\n * suitable for display. The root itself is rendered as \".\".\n */\nfunction relativeDir(dir: string, absRoot: string): string {\n const rel = relative(absRoot, dir)\n return rel === '' ? '.' : rel\n}\n\nfunction isDirectory(p: string): boolean {\n try {\n return statSync(p).isDirectory()\n } catch {\n return false\n }\n}\n","import yaml from 'js-yaml'\nimport type { AgentContext, AgentSection } from '../types'\n\nexport class AgentParser {\n /**\n * Parse an AGENT.md content into a structured AgentContext\n */\n static parse(markdown: string): AgentContext {\n let content = markdown\n let metadata: Record<string, any> = {}\n\n // Parse Frontmatter\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/\n const match = markdown.match(frontmatterRegex)\n if (match) {\n try {\n metadata = yaml.load(match[1] as string) as Record<string, any>\n content = markdown.slice(match[0].length).trim()\n } catch (e) {\n console.error('Failed to parse Agent frontmatter:', e)\n }\n }\n\n const lines = content.split(/\\r?\\n/)\n const sections: AgentSection[] = []\n let title = metadata.name ?? 'Unknown Agent'\n let currentSection: AgentSection | null = null\n let currentContent: string[] = []\n\n for (const line of lines) {\n // Parse Title (Only if not already set by frontmatter)\n if (line.startsWith('# ') && !metadata.name) {\n const rawTitle = line.replace('# ', '').trim()\n // Handle \"AGENT CONTEXT: [Name]\" format\n if (rawTitle.toUpperCase().startsWith('AGENT CONTEXT:')) {\n title = rawTitle\n .slice(14)\n .replace(/^[:\\s-]+/, '')\n .trim()\n } else {\n title = rawTitle\n }\n continue\n }\n\n // Parse Sections\n if (line.startsWith('## ')) {\n // Save previous section\n if (currentSection) {\n currentSection.content = currentContent.join('\\n').trim()\n sections.push(currentSection)\n }\n\n currentSection = {\n title: line.replace('## ', '').trim(),\n content: '',\n }\n currentContent = []\n continue\n }\n\n // Collect content\n if (currentSection) {\n currentContent.push(line)\n }\n }\n\n // Save last section\n if (currentSection) {\n currentSection.content = currentContent.join('\\n').trim()\n sections.push(currentSection)\n }\n\n return {\n title,\n sections,\n metadata,\n }\n }\n}\n","import { existsSync } from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\n\nimport { AUTONOMOS_DIR } from '../constants'\n\n/**\n * Markers that identify the root of an Autonomos / git project.\n *\n * `.autonomos/` is a strong signal: if it exists, the project has already\n * been initialized with the protocol and the directory containing it is,\n * by definition, the project root.\n *\n * `.git/` is a weaker signal: it only tells us the directory is inside a\n * git working tree. We still stop at the first `.git/` we see, which is\n * good enough for the common monorepo case (the monorepo root contains\n * the `.git/`, package subdirectories do not).\n */\nconst PROJECT_MARKERS = [AUTONOMOS_DIR, '.git'] as const\n\n/**\n * Find the directory that owns this project by walking up from `startDir`\n * until we find a directory containing `.autonomos/` or `.git/`.\n *\n * Returns `null` if no such directory exists before we reach the\n * filesystem root.\n *\n * Notes on behavior:\n * - The search stops at the first directory that contains any of the\n * markers. For monorepos this is the monorepo root, not the package\n * directory the caller is sitting in.\n * - A directory containing `.git/` is preferred over walking further up:\n * this prevents leaking into a parent repository in nested-worktree\n * setups. Callers that need the absolute git toplevel can run\n * `git rev-parse --show-toplevel` themselves after this returns.\n *\n * @param startDir - Absolute path to start the search from.\n */\nexport function findProjectRoot(startDir: string): string | null {\n if (!startDir) return null\n const start = resolve(startDir)\n let current = start\n\n while (true) {\n if (PROJECT_MARKERS.some(marker => existsSync(join(current, marker)))) {\n return current\n }\n const parent = dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n\n/**\n * Check whether two absolute paths refer to the same directory.\n *\n * Resolves `.` / `..` segments before comparing, so `/a/b` and\n * `/a/b/./` are considered the same.\n */\nexport function isSamePath(a: string, b: string): boolean {\n if (!a || !b) return false\n return resolve(a) === resolve(b)\n}\n\n/**\n * Render a path relative to another path, with one guarantee that the\n * default `path.relative` doesn't give us: we never return a value that\n * starts with `..`. If `target` is not under `base`, we return the\n * absolute resolved path of `target` so the caller can still show a\n * useful location.\n */\nexport function displayRelative(target: string, base: string): string {\n const rel = relative(base, target)\n if (rel === '' || rel === '.') return '.'\n if (rel.startsWith(`..${sep}`) || rel === '..' || isAbsolute(rel)) {\n return resolve(target)\n }\n return rel\n}\n","import type { Complexity, Priority, Task, TaskStatus } from '../types'\n\nexport class TaskParser {\n static parse(markdown: string): Task[] {\n const tasks: Task[] = []\n const lines = markdown.split(/\\r?\\n/)\n const taskRegex = /- \\[([ x/!])\\] \\*\\*\\[(.+)\\]\\*\\* (.+) `Priority: (.+)` `Complexity: (.+)`/\n\n for (const line of lines) {\n const match = line.match(taskRegex)\n if (match) {\n const [, statusChar = ' ', id = '', title = '', priority = '', complexity = ''] =\n match\n tasks.push({\n id,\n title: title.trim(),\n priority: priority as Priority,\n complexity: complexity as Complexity,\n status: this.mapStatus(statusChar),\n })\n }\n }\n return tasks\n }\n\n private static mapStatus(char: string): TaskStatus {\n switch (char) {\n case ' ':\n return 'TODO'\n case '/':\n return 'IN_PROGRESS'\n case 'x':\n return 'DONE'\n case '!':\n return 'BLOCKED'\n default:\n return 'TODO'\n }\n }\n}\n","","import harnessCodesData from './data/harness-codes.json' with { type: 'json' }\nimport {\n HarnessCodesSchema,\n type Harness,\n type HarnessCodes,\n type Installer,\n} from './schemas/harness-codes'\n\n/**\n * Validated, in-memory representation of the harness codes config.\n * Loaded once at module init, validated via Zod.\n */\nconst codes: HarnessCodes = HarnessCodesSchema.parse(harnessCodesData)\n\n/**\n * Get a single harness entry by its id.\n * Throws if the id is unknown.\n */\nexport function getHarness(id: string): Harness {\n const entry = codes.platforms[id]\n if (!entry) {\n const known = Object.keys(codes.platforms).join(', ')\n throw new Error(`Unknown harness: \"${id}\". Known harnesses: ${known}`)\n }\n return entry\n}\n\n/**\n * List all configured harnesses, as an array of {id, harness} pairs.\n * Stable order: insertion order of the JSON object.\n */\nexport function listHarnesses(): Array<{ id: string; harness: Harness }> {\n return Object.entries(codes.platforms).map(([id, harness]) => ({ id, harness }))\n}\n\n/**\n * Get the list of preferred harnesses (shown as recommended options).\n */\nexport function listPreferredHarnesses(): Array<{ id: string; harness: Harness }> {\n return listHarnesses().filter(({ harness }) => harness.preferred)\n}\n\n/**\n * A resolved target directory where workflow files will be written.\n * One per unique path, with the list of harness ids that share it.\n */\nexport interface ResolvedTarget {\n /** Absolute or project-relative path to the directory */\n path: string\n /** File extension to use (e.g. \".md\", \".agent.md\") */\n fileExtension: string\n /** Ids of the harnesses that will read from this directory */\n usedBy: string[]\n}\n\n/**\n * Resolve the unique target directories for a set of harness ids.\n *\n * Harnesses that share the same `skillsDir` (e.g. Codex, OpenCode, KiloCode\n * all use `.agents/skills/`) are deduplicated: the directory appears once\n * in the output, with all the harness ids listed in `usedBy`.\n *\n * The `path` is returned relative to the project root (caller is responsible\n * for joining with the project cwd).\n */\nexport function resolveTargets(harnessIds: string[], cwd: string = '.'): ResolvedTarget[] {\n const map = new Map<string, ResolvedTarget>()\n\n for (const id of harnessIds) {\n const { installer } = getHarness(id)\n collectFromInstaller(map, installer, id, cwd)\n }\n\n return Array.from(map.values())\n}\n\nfunction collectFromInstaller(\n map: Map<string, ResolvedTarget>,\n installer: Installer,\n harnessId: string,\n cwd: string\n): void {\n const ext = installer.fileExtension\n if (installer.workflowsDir) {\n addTarget(map, joinPath(cwd, installer.workflowsDir), ext, harnessId)\n } else if (installer.targetDir) {\n addTarget(map, joinPath(cwd, installer.targetDir), ext, harnessId)\n } else if (installer.skillsDir) {\n addTarget(map, joinPath(cwd, installer.skillsDir), ext, harnessId)\n }\n if (installer.commandsDir) {\n addTarget(map, joinPath(cwd, installer.commandsDir), ext, harnessId)\n }\n}\n\nfunction addTarget(\n map: Map<string, ResolvedTarget>,\n path: string,\n fileExtension: string,\n harnessId: string\n): void {\n const existing = map.get(path)\n if (existing) {\n if (!existing.usedBy.includes(harnessId)) {\n existing.usedBy.push(harnessId)\n }\n } else {\n map.set(path, { path, fileExtension, usedBy: [harnessId] })\n }\n}\n\nfunction joinPath(a: string, b: string): string {\n if (a === '.' || a === '') return b\n if (b.startsWith('/')) return `${a}${b}`\n return `${a}/${b}`\n}\n\n/**\n * Get the raw (validated) codes object, for advanced use cases.\n * Most callers should use the higher-level helpers above.\n */\nexport function getRawHarnessCodes(): HarnessCodes {\n return codes\n}\n"],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ description: 'Mandatory close-out before ending a session. Forces durable knowle
|
|
|
6
6
|
# /crystallize — End session
|
|
7
7
|
|
|
8
8
|
> **CRITICAL:** You MUST NOT ask the user what to crystallize. This is YOUR job. Reflect, decide, write. Then inform the user what you saved.
|
|
9
|
+
> **Authority:** If the user limited the work to read-only or no changes, do not modify any artifact; deliver the substantive answer and report that crystallization was skipped.
|
|
9
10
|
|
|
10
11
|
## STEP 1 — Worklog
|
|
11
12
|
|
|
@@ -16,17 +17,19 @@ Create `.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md` containing:
|
|
|
16
17
|
- Files modified
|
|
17
18
|
- Next steps for the next session
|
|
18
19
|
|
|
19
|
-
## STEP 2 —
|
|
20
|
+
## STEP 2 — Route knowledge
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
For each candidate ask: **Would this still guide a different future task?**
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
- **No:** keep observations, measurements, chronology, and completed actions in the worklog.
|
|
25
|
+
- **Operational explanation:** update existing component documentation when within scope.
|
|
26
|
+
- **Yes:** add only stable, normative, non-duplicated guidance to the narrowest applicable `AGENT.md`.
|
|
27
|
+
|
|
28
|
+
Consolidate or replace superseded entries; remove disproven guidance. Never create an `AGENT.md` based on file count alone.
|
|
26
29
|
|
|
27
30
|
## STEP 3 — Task status
|
|
28
31
|
|
|
29
|
-
Mark
|
|
32
|
+
Mark `[x]` only if complete, `[!]` only if an unresolved dependency prevents progress, or keep `[/]` for partial work.
|
|
30
33
|
|
|
31
34
|
## STEP 4 — User response
|
|
32
35
|
|
|
@@ -34,4 +37,4 @@ First, deliver a self-contained answer to the original request: outcome, evidenc
|
|
|
34
37
|
|
|
35
38
|
Then append this supplementary handoff:
|
|
36
39
|
|
|
37
|
-
`Crystallization — Task: [x] / [!] — [ID] | Worklog: .autonomos/worklogs/... | AGENT.md updated: [yes / no — reason]`
|
|
40
|
+
`Crystallization — Task: [x] / [/] / [!] — [ID] | Worklog: .autonomos/worklogs/... | AGENT.md updated: [yes / no — reason]`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: protocol-issue
|
|
3
|
+
description: 'Optional intake for problems, proposals, and questions before choosing implementation.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /issue — Capture and triage
|
|
7
|
+
|
|
8
|
+
> Use this workflow only when the need or solution requires triage. A direct, clear, authorized change may start as a task.
|
|
9
|
+
|
|
10
|
+
## STEP 1 — Build context
|
|
11
|
+
|
|
12
|
+
1. Read root and applicable root → target `AGENT.md` files.
|
|
13
|
+
2. Read `.autonomos/ISSUES.md` if it exists and search for duplicates.
|
|
14
|
+
3. Read related tasks or worklogs only when they provide evidence.
|
|
15
|
+
|
|
16
|
+
## STEP 2 — Record the signal
|
|
17
|
+
|
|
18
|
+
Create `.autonomos/ISSUES.md` on first use. Record without prescribing implementation:
|
|
19
|
+
|
|
20
|
+
```markdown
|
|
21
|
+
## [ISSUE-ID] Concise title
|
|
22
|
+
|
|
23
|
+
- Type: problem | proposal | question
|
|
24
|
+
- Status: open | accepted | resolved | declined
|
|
25
|
+
- Evidence: observed facts or motivation
|
|
26
|
+
- Impact: why it matters
|
|
27
|
+
- Desired outcome: solution-independent success
|
|
28
|
+
- Tasks: none | TASK-ID, ...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Merge duplicate evidence into the existing issue instead of creating another.
|
|
32
|
+
|
|
33
|
+
## STEP 3 — Triage
|
|
34
|
+
|
|
35
|
+
- **Open:** preserve the signal; do not create a task before an approach is accepted.
|
|
36
|
+
- **Accepted:** create one or more scoped tasks through `/task` and link both directions.
|
|
37
|
+
- **Resolved/declined:** record the outcome and concise rationale; preserve the issue as history.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: protocol-reconcile
|
|
3
|
+
description: 'Audit and safely reconcile accumulated drift across Autonomos artifacts.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /reconcile — Audit and repair drift
|
|
7
|
+
|
|
8
|
+
> Reconciliation is evidence-driven and bounded by user authority. Never guess through a semantic conflict or rewrite history to match the present.
|
|
9
|
+
|
|
10
|
+
## STEP 1 — Inventory and classify
|
|
11
|
+
|
|
12
|
+
1. Read root and applicable scoped `AGENT.md` files, then current tasks, optional issues, relevant worklogs, and linked documentation.
|
|
13
|
+
2. Classify each artifact as current guidance, current state, historical evidence, or version-pinned protocol content.
|
|
14
|
+
3. Check protocol integrity with `autonomos status`; repair managed artifacts only through `autonomos update` when authorized.
|
|
15
|
+
|
|
16
|
+
## STEP 2 — Detect drift
|
|
17
|
+
|
|
18
|
+
Look for duplicates, contradictions, obsolete paths or technologies, misplaced knowledge, vague rules, broken references, and task/issue/worklog status mismatches.
|
|
19
|
+
|
|
20
|
+
## STEP 3 — Verify
|
|
21
|
+
|
|
22
|
+
1. Test each finding against authoritative repository source, configuration, tests, and current scoped documentation.
|
|
23
|
+
2. Use runtime or external evidence only when access is authorized and necessary.
|
|
24
|
+
3. Classify the result as **certain**, **uncertain**, or **historical-only**.
|
|
25
|
+
|
|
26
|
+
## STEP 4 — Reconcile
|
|
27
|
+
|
|
28
|
+
- **Certain:** make the smallest correction; consolidate duplicates, route misplaced content, and replace or remove disproven current guidance.
|
|
29
|
+
- **Uncertain:** do not mutate the disputed facts; report evidence, conflict, and concrete resolution options to the user.
|
|
30
|
+
- **Historical-only:** preserve it unless it exposes sensitive data or falsely claims to be current guidance.
|
|
31
|
+
|
|
32
|
+
Record material corrections and validation in the task worklog. Re-run checks and stop when a second pass produces no deterministic changes.
|
|
@@ -5,28 +5,29 @@ description: 'Mandatory bootstrap for any new session. Invoke before any work be
|
|
|
5
5
|
|
|
6
6
|
# /session — Start
|
|
7
7
|
|
|
8
|
-
**
|
|
8
|
+
> **Authority:** The protocol never expands the user's requested scope. Answer-only, read-only, and diagnosis-without-fix requests remain non-mutating.
|
|
9
9
|
|
|
10
|
-
## STEP 1 —
|
|
10
|
+
## STEP 1 — Orient
|
|
11
11
|
|
|
12
|
-
1.
|
|
13
|
-
2. Read
|
|
14
|
-
3. Read `.autonomos/TASKS.md`.
|
|
12
|
+
1. Read the root `AGENT.md`.
|
|
13
|
+
2. Read `.autonomos/TASKS.md`.
|
|
15
14
|
|
|
16
|
-
RESPOND with a **3-line max** summary of
|
|
15
|
+
RESPOND with a **3-line max** summary of relevant project context. Do not continue without this response.
|
|
17
16
|
|
|
18
|
-
## STEP 2 —
|
|
17
|
+
## STEP 2 — Resolve the objective
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
1. If the user supplied an objective, it takes precedence. Match a task, use `/issue` for untriaged signals, or register a task for a clear authorized change.
|
|
20
|
+
2. For non-mutating work, load only the context needed, answer, and do not start a task.
|
|
21
|
+
3. Without a user objective, resume a `[/]` task; otherwise pick the highest-priority `[ ]` task. If none exists, ask the user.
|
|
21
22
|
|
|
22
|
-
RESPOND: `Task: [ID] — [title]. Starting.`
|
|
23
|
+
RESPOND: `Task: [ID] — [title]. Starting.` when a task will run.
|
|
23
24
|
|
|
24
|
-
## STEP 3 —
|
|
25
|
+
## STEP 3 — Begin
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
Invoke `/task`; it owns scoped context, planning, and the `[/]` transition.
|
|
27
28
|
|
|
28
|
-
## Session rules
|
|
29
|
+
## Session rules
|
|
29
30
|
|
|
30
|
-
1.
|
|
31
|
-
2.
|
|
32
|
-
3.
|
|
31
|
+
1. Before non-trivial decisions, consult the applicable root → target `AGENT.md` chain.
|
|
32
|
+
2. Capture durable knowledge according to `/crystallize`, within user authority.
|
|
33
|
+
3. When authorized task work ends, invoke `/crystallize`.
|
|
@@ -5,12 +5,15 @@ description: 'Mandatory procedure before starting a new task. Invoke before touc
|
|
|
5
5
|
|
|
6
6
|
# /task — Begin a task
|
|
7
7
|
|
|
8
|
+
> **Authority:** Enter execution only for changes the user authorized. Answer-only, read-only, and diagnosis-without-fix requests must not mutate protocol or project artifacts.
|
|
9
|
+
|
|
8
10
|
**Do NOT touch code before Step 2 is done.**
|
|
9
11
|
|
|
10
12
|
## STEP 1 — Build fractal context
|
|
11
13
|
|
|
12
14
|
1. From the target file/folder, walk up to the project root. Read every `AGENT.md` you find on that path (root → target).
|
|
13
|
-
2.
|
|
15
|
+
2. Read the linked issue when present; if resuming, read the task's most recent worklog.
|
|
16
|
+
3. Do not load unrelated worklogs or context branches.
|
|
14
17
|
|
|
15
18
|
## STEP 2 — Declare plan
|
|
16
19
|
|
|
@@ -23,9 +26,9 @@ Mark the task `[/]` in `.autonomos/TASKS.md`, then work.
|
|
|
23
26
|
## During execution
|
|
24
27
|
|
|
25
28
|
1. **Before every non-trivial decision:** consult the relevant AGENT.md.
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
29
|
+
2. Treat new information as a crystallization candidate, not an automatic `AGENT.md` entry.
|
|
30
|
+
3. Keep session evidence with the task; route durable guidance only during `/crystallize`.
|
|
28
31
|
|
|
29
32
|
## End of task
|
|
30
33
|
|
|
31
|
-
Mark `[x]`
|
|
34
|
+
Mark `[x]` only if complete, `[!]` only if an unresolved dependency prevents progress, or keep `[/]` for partial work. Invoke `/crystallize`.
|
|
@@ -8,8 +8,8 @@ import { PROTOCOL_TEMPLATE } from '../templates/protocol'
|
|
|
8
8
|
* These tests guard against regressions on the v0.3 design:
|
|
9
9
|
* - No crystallization questions directed at the user
|
|
10
10
|
* - No duplicated close-out procedures in session.md
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
11
|
+
* - Scoped AGENT.md discovery (no CLI dependency in workflows)
|
|
12
|
+
* - Durable-memory admission, placement, and retirement
|
|
13
13
|
* - Workflows are short enough to fit in LLM working memory
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -20,6 +20,8 @@ function loadWorkflow(name: string): string {
|
|
|
20
20
|
const session = loadWorkflow('protocol-session.md')
|
|
21
21
|
const crystallize = loadWorkflow('protocol-crystallize.md')
|
|
22
22
|
const task = loadWorkflow('protocol-task.md')
|
|
23
|
+
const issue = loadWorkflow('protocol-issue.md')
|
|
24
|
+
const reconcile = loadWorkflow('protocol-reconcile.md')
|
|
23
25
|
|
|
24
26
|
// ---------------------------------------------------------------------------
|
|
25
27
|
// 1. Crystallization — agent-directed, never asks the user
|
|
@@ -30,7 +32,7 @@ describe('crystallize.md — self-directed crystallization', () => {
|
|
|
30
32
|
})
|
|
31
33
|
|
|
32
34
|
it('directs the agent to ask itself', () => {
|
|
33
|
-
expect(crystallize).toContain('
|
|
35
|
+
expect(crystallize).toContain('For each candidate ask')
|
|
34
36
|
})
|
|
35
37
|
|
|
36
38
|
it('does not contain a user-questioning pattern', () => {
|
|
@@ -43,7 +45,7 @@ describe('crystallize.md — self-directed crystallization', () => {
|
|
|
43
45
|
expect(crystallize).toContain('outcome, evidence, limitations, and relevant next step')
|
|
44
46
|
expect(crystallize).not.toContain('RESPOND with exactly')
|
|
45
47
|
expect(crystallize.indexOf('self-contained answer')).toBeLessThan(
|
|
46
|
-
crystallize.indexOf('supplementary handoff')
|
|
48
|
+
crystallize.indexOf('supplementary handoff')
|
|
47
49
|
)
|
|
48
50
|
})
|
|
49
51
|
})
|
|
@@ -72,19 +74,24 @@ describe('session.md — clean separation of concerns', () => {
|
|
|
72
74
|
})
|
|
73
75
|
|
|
74
76
|
// ---------------------------------------------------------------------------
|
|
75
|
-
// 3.
|
|
77
|
+
// 3. Scoped context discovery and workflow composition
|
|
76
78
|
// ---------------------------------------------------------------------------
|
|
77
|
-
describe('
|
|
78
|
-
it('
|
|
79
|
-
expect(session).toContain('
|
|
79
|
+
describe('Scoped context discovery and workflow composition', () => {
|
|
80
|
+
it('orients from root without loading every context branch', () => {
|
|
81
|
+
expect(session).toContain('Read the root `AGENT.md`')
|
|
82
|
+
expect(session).not.toContain('find . -name AGENT.md')
|
|
80
83
|
})
|
|
81
84
|
|
|
82
|
-
it('task.md
|
|
83
|
-
// task.md should instruct walking up the directory tree
|
|
85
|
+
it('task.md loads only the target ancestor chain and relevant worklog', () => {
|
|
84
86
|
expect(task).toContain('walk up')
|
|
85
|
-
|
|
87
|
+
expect(task).toContain('Do not load unrelated worklogs or context branches')
|
|
86
88
|
expect(task).not.toContain('npx --yes @autonomos/cli')
|
|
87
89
|
})
|
|
90
|
+
|
|
91
|
+
it('delegates scoped planning and task transition to /task', () => {
|
|
92
|
+
expect(session).toContain('Invoke `/task`')
|
|
93
|
+
expect(session).toContain('it owns scoped context, planning, and the `[/]` transition')
|
|
94
|
+
})
|
|
88
95
|
})
|
|
89
96
|
|
|
90
97
|
// ---------------------------------------------------------------------------
|
|
@@ -96,17 +103,10 @@ describe('AGENT.md format rules — consistent across files', () => {
|
|
|
96
103
|
expect(session).toContain('AGENT.md')
|
|
97
104
|
})
|
|
98
105
|
|
|
99
|
-
it('
|
|
100
|
-
expect(task).toContain('Root AGENT.md')
|
|
101
|
-
expect(task).toContain('free format')
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('crystallize.md allows free format for local files', () => {
|
|
105
|
-
expect(crystallize).toContain('free format')
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
it('PROTOCOL_TEMPLATE has explicit format rules section', () => {
|
|
106
|
+
it('PROTOCOL_TEMPLATE owns root vs local format rules', () => {
|
|
109
107
|
expect(PROTOCOL_TEMPLATE).toContain('Format Rules')
|
|
108
|
+
expect(PROTOCOL_TEMPLATE).toContain('Root `AGENT.md`')
|
|
109
|
+
expect(PROTOCOL_TEMPLATE).toContain('Local `AGENT.md`')
|
|
110
110
|
})
|
|
111
111
|
})
|
|
112
112
|
|
|
@@ -123,6 +123,8 @@ describe('PROTOCOL_TEMPLATE — v0.3 design', () => {
|
|
|
123
123
|
it('points to workflows as the executable contract', () => {
|
|
124
124
|
expect(PROTOCOL_TEMPLATE).toContain('/session')
|
|
125
125
|
expect(PROTOCOL_TEMPLATE).toContain('/task')
|
|
126
|
+
expect(PROTOCOL_TEMPLATE).toContain('/issue')
|
|
127
|
+
expect(PROTOCOL_TEMPLATE).toContain('/reconcile')
|
|
126
128
|
expect(PROTOCOL_TEMPLATE).toContain('/crystallize')
|
|
127
129
|
})
|
|
128
130
|
|
|
@@ -138,10 +140,125 @@ describe('PROTOCOL_TEMPLATE — v0.3 design', () => {
|
|
|
138
140
|
expect(PROTOCOL_TEMPLATE).toContain('.autonomos/TASKS.md')
|
|
139
141
|
expect(PROTOCOL_TEMPLATE).toContain('.autonomos/worklogs/')
|
|
140
142
|
})
|
|
143
|
+
|
|
144
|
+
it('documents scoped context and intent-first objective resolution', () => {
|
|
145
|
+
expect(PROTOCOL_TEMPLATE).toContain("selected scope's ancestor chain")
|
|
146
|
+
expect(PROTOCOL_TEMPLATE).toContain('Explicit user request first')
|
|
147
|
+
expect(PROTOCOL_TEMPLATE).not.toContain('find . -name AGENT.md')
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('distinguishes durable guidance from historical evidence', () => {
|
|
151
|
+
expect(PROTOCOL_TEMPLATE).toContain('Durable guidance for its directory scope')
|
|
152
|
+
expect(PROTOCOL_TEMPLATE).toContain('Historical session evidence')
|
|
153
|
+
expect(PROTOCOL_TEMPLATE).toContain('consolidate or replace obsolete entries')
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// 6. Durable-memory admission, placement, and retirement
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
describe('Durable-memory lifecycle', () => {
|
|
161
|
+
it('does not append every learning immediately', () => {
|
|
162
|
+
expect(task).toContain('crystallization candidate')
|
|
163
|
+
expect(task).not.toContain('Every new learning')
|
|
164
|
+
expect(task).not.toContain('append to an AGENT.md immediately')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('routes session evidence, operational docs, and durable guidance separately', () => {
|
|
168
|
+
expect(crystallize).toContain('Would this still guide a different future task?')
|
|
169
|
+
expect(crystallize).toContain('observations, measurements, chronology')
|
|
170
|
+
expect(crystallize).toContain('existing component documentation')
|
|
171
|
+
expect(crystallize).toContain('stable, normative, non-duplicated guidance')
|
|
172
|
+
expect(crystallize).toContain('narrowest applicable `AGENT.md`')
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('retires stale guidance and rejects arbitrary file-count heuristics', () => {
|
|
176
|
+
expect(crystallize).toContain('Consolidate or replace superseded entries')
|
|
177
|
+
expect(crystallize).toContain('remove disproven guidance')
|
|
178
|
+
expect(crystallize).toContain('Never create an `AGENT.md` based on file count alone')
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// 7. Optional issue intake and task separation
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
describe('Issue intake and task separation', () => {
|
|
186
|
+
it('keeps issue intake optional for requests that need triage', () => {
|
|
187
|
+
expect(issue).toContain('Use this workflow only when the need or solution requires triage')
|
|
188
|
+
expect(issue).toContain('A direct, clear, authorized change may start as a task')
|
|
189
|
+
expect(PROTOCOL_TEMPLATE).toContain('optional `ISSUES.md`')
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('records solution-independent evidence before implementation', () => {
|
|
193
|
+
expect(issue).toContain('Record without prescribing implementation')
|
|
194
|
+
expect(issue).toContain('Evidence: observed facts or motivation')
|
|
195
|
+
expect(issue).toContain('Desired outcome: solution-independent success')
|
|
196
|
+
expect(issue).toContain('search for duplicates')
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('creates tasks only after acceptance and links both directions', () => {
|
|
200
|
+
expect(issue).toContain('do not create a task before an approach is accepted')
|
|
201
|
+
expect(issue).toContain('create one or more scoped tasks through `/task`')
|
|
202
|
+
expect(issue).toContain('link both directions')
|
|
203
|
+
expect(PROTOCOL_TEMPLATE).toContain('Tasks describe an accepted intervention')
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// 8. Evidence-aware reconciliation
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
describe('Evidence-aware reconciliation', () => {
|
|
211
|
+
it('classifies current, historical, and version-pinned artifacts', () => {
|
|
212
|
+
expect(reconcile).toContain('current guidance, current state, historical evidence')
|
|
213
|
+
expect(reconcile).toContain('version-pinned protocol content')
|
|
214
|
+
expect(reconcile).toContain('autonomos status')
|
|
215
|
+
expect(reconcile).toContain('autonomos update')
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('checks the expected drift classes against authoritative evidence', () => {
|
|
219
|
+
expect(reconcile).toContain('duplicates, contradictions, obsolete paths or technologies')
|
|
220
|
+
expect(reconcile).toContain('authoritative repository source, configuration, tests')
|
|
221
|
+
expect(reconcile).toContain('certain**, **uncertain**, or **historical-only')
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
it('corrects only certain findings and converges idempotently', () => {
|
|
225
|
+
expect(reconcile).toContain('Certain:** make the smallest correction')
|
|
226
|
+
expect(reconcile).toContain('Uncertain:** do not mutate the disputed facts')
|
|
227
|
+
expect(reconcile).toContain('Historical-only:** preserve it')
|
|
228
|
+
expect(reconcile).toContain('second pass produces no deterministic changes')
|
|
229
|
+
})
|
|
141
230
|
})
|
|
142
231
|
|
|
143
232
|
// ---------------------------------------------------------------------------
|
|
144
|
-
//
|
|
233
|
+
// 9. User authority and truthful lifecycle status
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
describe('User authority and lifecycle status', () => {
|
|
236
|
+
it('keeps answer-only, read-only, and diagnostic requests non-mutating', () => {
|
|
237
|
+
expect(session).toContain("never expands the user's requested scope")
|
|
238
|
+
expect(session).toContain('answer, and do not start a task')
|
|
239
|
+
expect(task).toContain('diagnosis-without-fix requests must not mutate')
|
|
240
|
+
expect(crystallize).toContain('limited the work to read-only or no changes')
|
|
241
|
+
expect(crystallize).toContain('do not modify any artifact')
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('prioritizes explicit intent, then resumed work, then backlog priority', () => {
|
|
245
|
+
expect(session).toContain('user supplied an objective, it takes precedence')
|
|
246
|
+
expect(session).toContain('resume a `[/]` task')
|
|
247
|
+
expect(session).toContain('highest-priority `[ ]` task')
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
it('distinguishes complete, partial, and genuinely blocked work', () => {
|
|
251
|
+
for (const workflow of [task, crystallize]) {
|
|
252
|
+
expect(workflow).toContain('only if complete')
|
|
253
|
+
expect(workflow).toContain('unresolved dependency prevents progress')
|
|
254
|
+
expect(workflow).toContain('keep `[/]` for partial work')
|
|
255
|
+
}
|
|
256
|
+
expect(crystallize).toContain('Task: [x] / [/] / [!]')
|
|
257
|
+
})
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// 10. Workflow brevity — each must be concise enough for LLM working memory
|
|
145
262
|
// ---------------------------------------------------------------------------
|
|
146
263
|
describe('Workflow brevity', () => {
|
|
147
264
|
const maxLines = 35 // allowing some margin over the 30-line target
|
|
@@ -163,4 +280,16 @@ describe('Workflow brevity', () => {
|
|
|
163
280
|
const lines = body.trim().split('\n').length
|
|
164
281
|
expect(lines).toBeLessThanOrEqual(maxLines)
|
|
165
282
|
})
|
|
283
|
+
|
|
284
|
+
it(`issue.md is ≤${maxLines} lines (excluding frontmatter)`, () => {
|
|
285
|
+
const body = issue.replace(/^---[\s\S]*?---\n/, '')
|
|
286
|
+
const lines = body.trim().split('\n').length
|
|
287
|
+
expect(lines).toBeLessThanOrEqual(maxLines)
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it(`reconcile.md is ≤${maxLines} lines (excluding frontmatter)`, () => {
|
|
291
|
+
const body = reconcile.replace(/^---[\s\S]*?---\n/, '')
|
|
292
|
+
const lines = body.trim().split('\n').length
|
|
293
|
+
expect(lines).toBeLessThanOrEqual(maxLines)
|
|
294
|
+
})
|
|
166
295
|
})
|