@multileaf/ai-workflow 0.1.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.
Files changed (165) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +32 -0
  4. package/dist/adapter-contract.d.ts +13 -0
  5. package/dist/adapter-contract.js +50 -0
  6. package/dist/adapter.d.ts +15 -0
  7. package/dist/adapter.js +62 -0
  8. package/dist/claude-layout.d.ts +9 -0
  9. package/dist/claude-layout.js +23 -0
  10. package/dist/cli.d.ts +4 -0
  11. package/dist/cli.js +30 -0
  12. package/dist/codex-layout.d.ts +10 -0
  13. package/dist/codex-layout.js +24 -0
  14. package/dist/confirmation.d.ts +9 -0
  15. package/dist/confirmation.js +41 -0
  16. package/dist/constants.d.ts +3 -0
  17. package/dist/constants.js +10 -0
  18. package/dist/context-cache.d.ts +8 -0
  19. package/dist/context-cache.js +17 -0
  20. package/dist/context-quality.d.ts +11 -0
  21. package/dist/context-quality.js +27 -0
  22. package/dist/context-retrieval.d.ts +3 -0
  23. package/dist/context-retrieval.js +13 -0
  24. package/dist/context-store.d.ts +9 -0
  25. package/dist/context-store.js +18 -0
  26. package/dist/copilot-layout.d.ts +9 -0
  27. package/dist/copilot-layout.js +24 -0
  28. package/dist/cursor-layout.d.ts +9 -0
  29. package/dist/cursor-layout.js +25 -0
  30. package/dist/dashboard.d.ts +37 -0
  31. package/dist/dashboard.js +251 -0
  32. package/dist/drift.d.ts +2 -0
  33. package/dist/drift.js +10 -0
  34. package/dist/evidence.d.ts +20 -0
  35. package/dist/evidence.js +32 -0
  36. package/dist/files.d.ts +2 -0
  37. package/dist/files.js +58 -0
  38. package/dist/gemini-layout.d.ts +9 -0
  39. package/dist/gemini-layout.js +23 -0
  40. package/dist/generator.d.ts +3 -0
  41. package/dist/generator.js +16 -0
  42. package/dist/intelligence.d.ts +2 -0
  43. package/dist/intelligence.js +13 -0
  44. package/dist/interpreter.d.ts +23 -0
  45. package/dist/interpreter.js +117 -0
  46. package/dist/lockfile.d.ts +12 -0
  47. package/dist/lockfile.js +59 -0
  48. package/dist/manifest.d.ts +15 -0
  49. package/dist/manifest.js +35 -0
  50. package/dist/migration.d.ts +22 -0
  51. package/dist/migration.js +50 -0
  52. package/dist/orchestration.d.ts +30 -0
  53. package/dist/orchestration.js +172 -0
  54. package/dist/organization-policy.d.ts +14 -0
  55. package/dist/organization-policy.js +47 -0
  56. package/dist/package-audit.d.ts +19 -0
  57. package/dist/package-audit.js +28 -0
  58. package/dist/package-contract.d.ts +30 -0
  59. package/dist/package-contract.js +93 -0
  60. package/dist/package-integrity.d.ts +8 -0
  61. package/dist/package-integrity.js +15 -0
  62. package/dist/package-updates.d.ts +11 -0
  63. package/dist/package-updates.js +32 -0
  64. package/dist/plugin-sdk.d.ts +20 -0
  65. package/dist/plugin-sdk.js +243 -0
  66. package/dist/policy-gate.d.ts +6 -0
  67. package/dist/policy-gate.js +20 -0
  68. package/dist/profile.d.ts +23 -0
  69. package/dist/profile.js +123 -0
  70. package/dist/providers.d.ts +20 -0
  71. package/dist/providers.js +67 -0
  72. package/dist/quality-gates.d.ts +2 -0
  73. package/dist/quality-gates.js +40 -0
  74. package/dist/recommendations.d.ts +12 -0
  75. package/dist/recommendations.js +63 -0
  76. package/dist/registry.d.ts +11 -0
  77. package/dist/registry.js +27 -0
  78. package/dist/scanner.d.ts +9 -0
  79. package/dist/scanner.js +83 -0
  80. package/dist/selection.d.ts +3 -0
  81. package/dist/selection.js +11 -0
  82. package/dist/self-validation.d.ts +9 -0
  83. package/dist/self-validation.js +9 -0
  84. package/dist/services.d.ts +42 -0
  85. package/dist/services.js +1 -0
  86. package/dist/team-configuration.d.ts +23 -0
  87. package/dist/team-configuration.js +104 -0
  88. package/dist/telemetry.d.ts +20 -0
  89. package/dist/telemetry.js +95 -0
  90. package/dist/token-usage.d.ts +9 -0
  91. package/dist/token-usage.js +38 -0
  92. package/dist/traceability.d.ts +23 -0
  93. package/dist/traceability.js +51 -0
  94. package/dist/types.d.ts +22 -0
  95. package/dist/types.js +1 -0
  96. package/dist/universal-layout.d.ts +9 -0
  97. package/dist/universal-layout.js +21 -0
  98. package/dist/vercel-skills.d.ts +17 -0
  99. package/dist/vercel-skills.js +49 -0
  100. package/dist/workflow.d.ts +4 -0
  101. package/dist/workflow.js +1130 -0
  102. package/docs/README.md +20 -0
  103. package/docs/adapter-model.md +16 -0
  104. package/docs/architecture.md +66 -0
  105. package/docs/backlog.md +93 -0
  106. package/docs/orchestration.md +50 -0
  107. package/docs/package-model.md +53 -0
  108. package/docs/plugin-authoring.md +31 -0
  109. package/docs/product-requirements.md +57 -0
  110. package/docs/product-vision.md +26 -0
  111. package/docs/project-intelligence.md +59 -0
  112. package/docs/quality.md +32 -0
  113. package/docs/release-backlog.md +7 -0
  114. package/docs/release-process.md +38 -0
  115. package/docs/security.md +18 -0
  116. package/docs/telemetry.md +28 -0
  117. package/docs/token-efficiency.md +16 -0
  118. package/package.json +76 -0
  119. package/resources/README.md +4 -0
  120. package/resources/agents/adapter-engineer.md +4 -0
  121. package/resources/agents/documentation-writer.md +4 -0
  122. package/resources/agents/quality-reviewer.md +4 -0
  123. package/resources/agents/requirements-analyst.md +4 -0
  124. package/resources/agents/security-reviewer.md +4 -0
  125. package/resources/agents/technical-architect.md +4 -0
  126. package/resources/agents/test-engineer.md +4 -0
  127. package/resources/agents/typescript-engineer.md +4 -0
  128. package/resources/hooks/post-change.md +4 -0
  129. package/resources/hooks/post-implementation.md +4 -0
  130. package/resources/hooks/pre-commit.md +4 -0
  131. package/resources/hooks/pre-implementation.md +4 -0
  132. package/resources/hooks/pre-release.md +4 -0
  133. package/resources/package.yaml +36 -0
  134. package/resources/rules/architecture-policy.md +4 -0
  135. package/resources/rules/completion-validation.md +19 -0
  136. package/resources/rules/dependency-policy.md +4 -0
  137. package/resources/rules/documentation-policy.md +4 -0
  138. package/resources/rules/generated-files.md +4 -0
  139. package/resources/rules/language-policy.md +4 -0
  140. package/resources/rules/quality-gates.md +4 -0
  141. package/resources/rules/security-policy.md +4 -0
  142. package/resources/rules/self-validation.md +12 -0
  143. package/resources/rules/tdd-policy.md +4 -0
  144. package/resources/skills/adapter-development.md +9 -0
  145. package/resources/skills/brainstorming.md +9 -0
  146. package/resources/skills/code-review.md +9 -0
  147. package/resources/skills/documentation-maintenance.md +9 -0
  148. package/resources/skills/implementation-planning.md +9 -0
  149. package/resources/skills/project-init.md +9 -0
  150. package/resources/skills/requirements-specification.md +9 -0
  151. package/resources/skills/security-review.md +9 -0
  152. package/resources/skills/skill-authoring.md +9 -0
  153. package/resources/skills/tdd-development.md +9 -0
  154. package/resources/skills/technical-design.md +9 -0
  155. package/resources/skills/verification.md +9 -0
  156. package/resources/templates/brainstorm.md +16 -0
  157. package/resources/templates/decision-record.md +12 -0
  158. package/resources/templates/implementation-plan.md +12 -0
  159. package/resources/templates/migration-report.md +14 -0
  160. package/resources/templates/security-review.md +14 -0
  161. package/resources/templates/specification.md +23 -0
  162. package/resources/templates/task.md +14 -0
  163. package/resources/templates/technical-design.md +14 -0
  164. package/resources/templates/test-plan.md +12 -0
  165. package/resources/templates/verification-report.md +12 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file. The format follows Keep a Changelog, and versions follow Semantic Versioning.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.1.0] - 2026-09-04
8
+
9
+ ### Added
10
+
11
+ - Portable installation and migration across Codex, Claude Code, Cursor, Gemini CLI, GitHub Copilot, and a universal target.
12
+ - Hybrid deterministic and AI-assisted project scanning, recommendations, personalization, and confirmation workflows.
13
+ - Spec-driven brainstorming, requirements, decisions, implementation planning, verification, quality gates, and traceability.
14
+ - Versioned packages, registries, Vercel Skills integration, policy enforcement, integrity verification, and update workflows.
15
+ - Layered context, token budgets, opt-in telemetry, plugin SDK, local dashboard, and provider-neutral multi-agent orchestration.
16
+
17
+ ### Security
18
+
19
+ - Path confinement, symlink protection, explicit permission gates, secret redaction, strict parsers, atomic migrations, and immutable execution checkpoints.
20
+
21
+ [Unreleased]: https://github.com/MultiLeaf/aiw/compare/v0.1.0...HEAD
22
+ [0.1.0]: https://github.com/MultiLeaf/aiw/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MultiLeaf
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # AI Workflow
2
+
3
+ Portable spec-driven development workflow for AI coding agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx @multileaf/ai-workflow install --target codex
9
+ ```
10
+
11
+ Replace `codex` with `claude`, `cursor`, `gemini`, `copilot`, or `universal` when needed. Every command follows `npx @multileaf/ai-workflow <command> <options>`.
12
+
13
+ ## Development
14
+
15
+ ```bash
16
+ npm install
17
+ npm run build
18
+ node dist/cli.js install --target codex
19
+ node dist/cli.js ui
20
+ ```
21
+
22
+ The project configuration lives in `.aiw/`; target-specific files are generated by adapters.
23
+
24
+ Telemetry is disabled by default. Use `aiw telemetry status`, `enable`, or `disable` to manage explicit privacy preferences. See [Telemetry and Privacy](docs/telemetry.md).
25
+
26
+ Create portable plugins with `aiw plugin create` and validate them with `aiw plugin validate`. The typed SDK is exported from `@multileaf/ai-workflow/plugin-sdk`; see [Plugin Authoring](docs/plugin-authoring.md).
27
+
28
+ Inspect project state in the local dashboard with `aiw ui`. It binds to `127.0.0.1`, loads only `.aiw/` project state, and requires explicit confirmation before target migration.
29
+
30
+ Preview a versioned multi-agent task graph with `aiw orchestrate --plan=orchestration.yml`. Execution is opt-in through `--execute`, uses a host-provided agent adapter, limits concurrency with `--max-parallel`, and records results under `.aiw/checkpoints/`. The scheduler and adapter contract are exported from `@multileaf/ai-workflow/orchestration`; see [Multi-agent Orchestration](docs/orchestration.md).
31
+
32
+ Release candidates must pass `npm run release:check`. AI Workflow is available under the MIT License.
@@ -0,0 +1,13 @@
1
+ import { type ResourceType } from "./package-contract.js";
2
+ import { type Target } from "./types.js";
3
+ export declare const LIFECYCLE_EVENTS: readonly ["install", "update", "remove", "validate"];
4
+ export type LifecycleEvent = (typeof LIFECYCLE_EVENTS)[number];
5
+ export type AdapterCapabilities = {
6
+ target: Target;
7
+ resources: ResourceType[];
8
+ events: LifecycleEvent[];
9
+ fallback: boolean;
10
+ };
11
+ export declare const ADAPTER_CAPABILITIES: Readonly<Record<Target, AdapterCapabilities>>;
12
+ export declare function getAdapterCapabilities(target: string): AdapterCapabilities;
13
+ export declare function serializeAdapterCapabilities(target: string): string;
@@ -0,0 +1,50 @@
1
+ import { RESOURCE_TYPES } from "./package-contract.js";
2
+ import { TARGETS } from "./types.js";
3
+ export const LIFECYCLE_EVENTS = ["install", "update", "remove", "validate"];
4
+ export const ADAPTER_CAPABILITIES = {
5
+ codex: {
6
+ target: "codex",
7
+ resources: [...RESOURCE_TYPES],
8
+ events: [...LIFECYCLE_EVENTS],
9
+ fallback: false,
10
+ },
11
+ claude: {
12
+ target: "claude",
13
+ resources: ["skills", "rules", "agents", "hooks", "templates"],
14
+ events: [...LIFECYCLE_EVENTS],
15
+ fallback: false,
16
+ },
17
+ cursor: {
18
+ target: "cursor",
19
+ resources: ["skills", "rules", "agents", "hooks", "templates"],
20
+ events: [...LIFECYCLE_EVENTS],
21
+ fallback: false,
22
+ },
23
+ gemini: {
24
+ target: "gemini",
25
+ resources: ["skills", "rules", "agents", "hooks", "templates"],
26
+ events: [...LIFECYCLE_EVENTS],
27
+ fallback: false,
28
+ },
29
+ copilot: {
30
+ target: "copilot",
31
+ resources: ["skills", "rules", "agents", "hooks", "templates"],
32
+ events: [...LIFECYCLE_EVENTS],
33
+ fallback: false,
34
+ },
35
+ universal: {
36
+ target: "universal",
37
+ resources: [...RESOURCE_TYPES],
38
+ events: [...LIFECYCLE_EVENTS],
39
+ fallback: true,
40
+ },
41
+ };
42
+ export function getAdapterCapabilities(target) {
43
+ if (!TARGETS.includes(target))
44
+ throw new Error(`Unsupported adapter target: ${target}`);
45
+ return ADAPTER_CAPABILITIES[target];
46
+ }
47
+ export function serializeAdapterCapabilities(target) {
48
+ const capabilities = getAdapterCapabilities(target);
49
+ return `target: ${capabilities.target}\nresources: [${capabilities.resources.join(", ")}]\nevents: [${capabilities.events.join(", ")}]\nfallback: ${capabilities.fallback}\n`;
50
+ }
@@ -0,0 +1,15 @@
1
+ import { type Target, type FileSystem } from "./types.js";
2
+ import type { ResourceType } from "./package-contract.js";
3
+ export declare function isTarget(value: string): value is Target;
4
+ export declare function detectTarget(root: string, fs: FileSystem): Target | undefined;
5
+ export declare function generateAiInit(root: string, target: string, fs: FileSystem): void;
6
+ export declare function renderAiInitPath(target: Target): string;
7
+ export declare function renderResourcePath(target: Target, type: ResourceType, id: string): string;
8
+ export type AdapterResourceType = ResourceType | "context";
9
+ export type AdapterSupport = "native" | "compatibility" | "fallback";
10
+ export type AdapterResourceDescriptor = {
11
+ path: string;
12
+ support: AdapterSupport;
13
+ };
14
+ export declare function describeResource(target: Target, type: AdapterResourceType, id: string): AdapterResourceDescriptor;
15
+ export declare function renderCodexResource(type: ResourceType, id: string, content: string, root: string, fs: FileSystem): string;
@@ -0,0 +1,62 @@
1
+ import { join } from "node:path";
2
+ import { TARGETS } from "./types.js";
3
+ import { getAdapterCapabilities } from "./adapter-contract.js";
4
+ import { describeCodexResource } from "./codex-layout.js";
5
+ import { describeClaudeResource } from "./claude-layout.js";
6
+ import { describeCursorResource } from "./cursor-layout.js";
7
+ import { describeGeminiResource } from "./gemini-layout.js";
8
+ import { describeCopilotResource } from "./copilot-layout.js";
9
+ import { describeUniversalResource } from "./universal-layout.js";
10
+ export function isTarget(value) {
11
+ return TARGETS.includes(value);
12
+ }
13
+ export function detectTarget(root, fs) {
14
+ const markers = [
15
+ ["codex", ".agents"],
16
+ ["claude", ".claude"],
17
+ ["cursor", ".cursor"],
18
+ ["gemini", ".gemini"],
19
+ ["copilot", ".github/copilot-instructions.md"],
20
+ ];
21
+ return markers.find(([, marker]) => fs.exists(join(root, marker)))?.[0];
22
+ }
23
+ export function generateAiInit(root, target, fs) {
24
+ if (!isTarget(target))
25
+ throw new Error(`Unsupported target: ${target}`);
26
+ getAdapterCapabilities(target);
27
+ fs.write(join(root, renderAiInitPath(target)), `---\nname: ai-init\ndescription: Analyze the project and configure AI Workflow.\n---\n\n# AI Init\n\nAnalyze the repository safely and recommend project-specific capabilities.\n\n## Language Policy\n\nAll generated AI Workflow artifacts must be written in English unless the user explicitly requests another language.\n`);
28
+ }
29
+ export function renderAiInitPath(target) {
30
+ const paths = {
31
+ codex: ".agents/skills/ai-init/SKILL.md",
32
+ claude: ".claude/skills/ai-init/SKILL.md",
33
+ cursor: ".cursor/skills/ai-init/SKILL.md",
34
+ gemini: ".gemini/skills/ai-init/SKILL.md",
35
+ copilot: ".github/copilot-instructions.md",
36
+ universal: ".aiw/resources/skills/ai-init.md",
37
+ };
38
+ return paths[target];
39
+ }
40
+ export function renderResourcePath(target, type, id) {
41
+ return describeResource(target, type, id).path;
42
+ }
43
+ export function describeResource(target, type, id) {
44
+ if (!isTarget(target))
45
+ throw new Error(`Adapter rendering is not implemented for target: ${target}`);
46
+ if (target === "codex")
47
+ return describeCodexResource(type, id);
48
+ if (target === "claude")
49
+ return describeClaudeResource(type, id);
50
+ if (target === "cursor")
51
+ return describeCursorResource(type, id);
52
+ if (target === "gemini")
53
+ return describeGeminiResource(type, id);
54
+ if (target === "copilot")
55
+ return describeCopilotResource(type, id);
56
+ return describeUniversalResource(type, id);
57
+ }
58
+ export function renderCodexResource(type, id, content, root, fs) {
59
+ const path = renderResourcePath("codex", type, id);
60
+ fs.write(join(root, path), content);
61
+ return path;
62
+ }
@@ -0,0 +1,9 @@
1
+ import type { ResourceType } from "./package-contract.js";
2
+ import type { FileSystem } from "./types.js";
3
+ export type ClaudeResourceType = ResourceType | "context";
4
+ export type ClaudeResourceDescriptor = {
5
+ path: string;
6
+ support: "native" | "compatibility";
7
+ };
8
+ export declare function describeClaudeResource(type: ClaudeResourceType, id: string): ClaudeResourceDescriptor;
9
+ export declare function renderClaudeContext(root: string, content: string, fs: FileSystem): string;
@@ -0,0 +1,23 @@
1
+ import { join } from "node:path";
2
+ export function describeClaudeResource(type, id) {
3
+ const native = {
4
+ skills: `.claude/skills/${id}/SKILL.md`,
5
+ rules: `.claude/rules/${id}.md`,
6
+ agents: `.claude/agents/${id}.md`,
7
+ context: "CLAUDE.md",
8
+ };
9
+ if (native[type])
10
+ return { path: native[type], support: "native" };
11
+ const compatibility = {
12
+ hooks: `.claude/aiw/hooks/${id}.md`,
13
+ templates: `.claude/aiw/templates/${id}.md`,
14
+ };
15
+ if (compatibility[type])
16
+ return { path: compatibility[type], support: "compatibility" };
17
+ throw new Error(`Unsupported Claude resource type: ${type}`);
18
+ }
19
+ export function renderClaudeContext(root, content, fs) {
20
+ const path = describeClaudeResource("context", "project").path;
21
+ fs.write(join(root, path), content);
22
+ return path;
23
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { type WorkflowServices } from "./workflow.js";
3
+ import type { CommandResult } from "./types.js";
4
+ export declare function run(args: string[], root?: string, services?: WorkflowServices): Promise<CommandResult>;
package/dist/cli.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { nodeFileSystem } from "./files.js";
3
+ import { runCommand } from "./workflow.js";
4
+ import { recordConfiguredTelemetry } from "./telemetry.js";
5
+ import { join } from "node:path";
6
+ import { startDashboard } from "./dashboard.js";
7
+ export function run(args, root = process.cwd(), services = {}) {
8
+ return runWithTelemetry(args, root, services);
9
+ }
10
+ async function runWithTelemetry(args, root, services) {
11
+ const dependencies = {
12
+ dashboard: {
13
+ start: (dashboardRoot, port) => startDashboard(dashboardRoot, nodeFileSystem, (commandArgs) => runCommand(commandArgs, dashboardRoot, nodeFileSystem, services), port),
14
+ },
15
+ ...services,
16
+ };
17
+ const result = await runCommand(args, root, nodeFileSystem, dependencies);
18
+ if (args[0] === "ui" || (args[0] === "telemetry" && result.exitCode !== 0))
19
+ return result;
20
+ await recordConfiguredTelemetry(nodeFileSystem, join(root, ".aiw/telemetry.yml"), services.telemetry, args[0], result);
21
+ return result;
22
+ }
23
+ if (process.argv[1]?.endsWith("cli.js") || process.argv[1]?.endsWith("/aiw")) {
24
+ const result = await run(process.argv.slice(2));
25
+ if (result.output)
26
+ console.log(result.output);
27
+ if (result.error)
28
+ console.error(result.error);
29
+ process.exitCode = result.exitCode;
30
+ }
@@ -0,0 +1,10 @@
1
+ import type { ResourceType } from "./package-contract.js";
2
+ import type { FileSystem } from "./types.js";
3
+ export type CodexResourceType = ResourceType | "context";
4
+ export type CodexSupport = "native" | "compatibility";
5
+ export type CodexResourceDescriptor = {
6
+ path: string;
7
+ support: CodexSupport;
8
+ };
9
+ export declare function describeCodexResource(type: CodexResourceType, id: string): CodexResourceDescriptor;
10
+ export declare function renderCodexContext(root: string, content: string, fs: FileSystem): string;
@@ -0,0 +1,24 @@
1
+ import { join } from "node:path";
2
+ const COMPATIBILITY_ROOTS = {
3
+ rules: ".agents/rules",
4
+ agents: ".agents/agents",
5
+ hooks: ".agents/hooks",
6
+ templates: ".agents/templates",
7
+ };
8
+ export function describeCodexResource(type, id) {
9
+ if (type === "skills")
10
+ return { path: `.agents/skills/${id}/SKILL.md`, support: "native" };
11
+ if (type === "context")
12
+ return { path: "AGENTS.md", support: "native" };
13
+ if (!(type in COMPATIBILITY_ROOTS))
14
+ throw new Error(`Unsupported Codex resource type: ${type}`);
15
+ return {
16
+ path: `${COMPATIBILITY_ROOTS[type]}/${id}/${id}.md`,
17
+ support: "compatibility",
18
+ };
19
+ }
20
+ export function renderCodexContext(root, content, fs) {
21
+ const descriptor = describeCodexResource("context", "project");
22
+ fs.write(join(root, descriptor.path), content);
23
+ return descriptor.path;
24
+ }
@@ -0,0 +1,9 @@
1
+ import type { EvidenceFact } from "./evidence.js";
2
+ export type FactOverride = {
3
+ key: string;
4
+ action: "accept" | "reject" | "edit";
5
+ value?: string;
6
+ };
7
+ export declare function serializeOverrides(overrides: FactOverride[]): string;
8
+ export declare function parseOverrides(content: string): FactOverride[];
9
+ export declare function applyOverrides(facts: EvidenceFact[], overrides: FactOverride[]): EvidenceFact[];
@@ -0,0 +1,41 @@
1
+ export function serializeOverrides(overrides) {
2
+ return `schema: 1\noverrides:\n${overrides.map((item) => ` - key: ${item.key}\n action: ${item.action}${item.value ? `\n value: ${item.value}` : ""}`).join("\n")}\n`;
3
+ }
4
+ export function parseOverrides(content) {
5
+ const overrides = [];
6
+ const blocks = content.split(/(?=\s{2}- key:)/).slice(1);
7
+ for (const block of blocks) {
8
+ const key = block.match(/key: (.+)/)?.[1]?.trim();
9
+ const action = block.match(/action: (accept|reject|edit)/)?.[1];
10
+ const value = block.match(/value: (.+)/)?.[1]?.trim();
11
+ if (key && action)
12
+ overrides.push({ key, action, ...(value ? { value } : {}) });
13
+ }
14
+ return overrides;
15
+ }
16
+ export function applyOverrides(facts, overrides) {
17
+ return facts.flatMap((fact) => {
18
+ const override = overrides.find((item) => item.key === fact.key);
19
+ if (!override || override.action === "accept")
20
+ return [
21
+ {
22
+ ...fact,
23
+ ...(override ? { state: "confirmed", method: "user-confirmed" } : {}),
24
+ },
25
+ ];
26
+ if (override.action === "reject")
27
+ return [];
28
+ if (!override.value)
29
+ throw new Error(`An edited fact requires a value: ${fact.key}`);
30
+ return [
31
+ {
32
+ ...fact,
33
+ value: override.value,
34
+ state: "confirmed",
35
+ method: "user-confirmed",
36
+ confidence: 1,
37
+ evidence: [],
38
+ },
39
+ ];
40
+ });
41
+ }
@@ -0,0 +1,3 @@
1
+ export declare const WORKFLOW_DIRECTORY = ".aiw";
2
+ export declare const BASE_DIRECTORIES: string[];
3
+ export declare const INSTALL_USAGE = "aiw install [--target target] | scan | status | target <target> | validate";
@@ -0,0 +1,10 @@
1
+ export const WORKFLOW_DIRECTORY = ".aiw";
2
+ export const BASE_DIRECTORIES = [
3
+ "checkpoints",
4
+ "generated/specs",
5
+ "generated/plans",
6
+ "generated/docs",
7
+ "generated/artifacts",
8
+ "context",
9
+ ];
10
+ export const INSTALL_USAGE = "aiw install [--target target] | scan | status | target <target> | validate";
@@ -0,0 +1,8 @@
1
+ export type ContextSummaryCache = {
2
+ sourceChecksum: string;
3
+ summary: string;
4
+ };
5
+ export declare function createSummaryCache(source: string, summary: string): ContextSummaryCache;
6
+ export declare function isSummaryFresh(source: string, cache: ContextSummaryCache): boolean;
7
+ export declare function serializeSummaryCache(cache: ContextSummaryCache): string;
8
+ export declare function parseSummaryCache(content: string): ContextSummaryCache;
@@ -0,0 +1,17 @@
1
+ import { checksumPackage } from "./package-integrity.js";
2
+ export function createSummaryCache(source, summary) {
3
+ return { sourceChecksum: checksumPackage(source), summary };
4
+ }
5
+ export function isSummaryFresh(source, cache) {
6
+ return checksumPackage(source) === cache.sourceChecksum;
7
+ }
8
+ export function serializeSummaryCache(cache) {
9
+ return `schema: 1\nsource_checksum: ${cache.sourceChecksum}\nsummary: ${JSON.stringify(cache.summary)}\n`;
10
+ }
11
+ export function parseSummaryCache(content) {
12
+ const sourceChecksum = content.match(/^source_checksum:\s*(.+)$/m)?.[1]?.trim();
13
+ const summary = content.match(/^summary:\s*(.+)$/m)?.[1];
14
+ if (!sourceChecksum || summary === undefined)
15
+ throw new Error("Invalid context summary cache.");
16
+ return { sourceChecksum, summary: JSON.parse(summary) };
17
+ }
@@ -0,0 +1,11 @@
1
+ import type { ContextStore } from "./context-store.js";
2
+ export type ContextQuality = {
3
+ layers: number;
4
+ nonEmptyLayers: number;
5
+ characters: number;
6
+ estimatedTokens: number;
7
+ uniqueLines: number;
8
+ duplicateLines: number;
9
+ };
10
+ export declare function measureContextQuality(store: ContextStore): ContextQuality;
11
+ export declare function serializeContextQuality(metrics: ContextQuality): string;
@@ -0,0 +1,27 @@
1
+ export function measureContextQuality(store) {
2
+ const values = Object.values(store.layers);
3
+ const lines = values.flatMap((value) => value
4
+ .split("\n")
5
+ .map((line) => line.trim())
6
+ .filter(Boolean));
7
+ const uniqueLines = new Set(lines).size;
8
+ return {
9
+ layers: values.length,
10
+ nonEmptyLayers: values.filter((value) => value.trim()).length,
11
+ characters: values.join("\n").length,
12
+ estimatedTokens: Math.ceil(values.join("\n").length / 4),
13
+ uniqueLines,
14
+ duplicateLines: lines.length - uniqueLines,
15
+ };
16
+ }
17
+ export function serializeContextQuality(metrics) {
18
+ return ([
19
+ "schema: 1",
20
+ `layers: ${metrics.layers}`,
21
+ `non_empty_layers: ${metrics.nonEmptyLayers}`,
22
+ `characters: ${metrics.characters}`,
23
+ `estimated_tokens: ${metrics.estimatedTokens}`,
24
+ `unique_lines: ${metrics.uniqueLines}`,
25
+ `duplicate_lines: ${metrics.duplicateLines}`,
26
+ ].join("\n") + "\n");
27
+ }
@@ -0,0 +1,3 @@
1
+ import type { ContextStore } from "./context-store.js";
2
+ export declare function retrieveTaskContext(store: ContextStore): string;
3
+ export declare function loadContextDelta(previous: string, current: string): string;
@@ -0,0 +1,13 @@
1
+ export function retrieveTaskContext(store) {
2
+ return ["global", "project", "task"]
3
+ .map((layer) => store.layers[layer].trim())
4
+ .filter(Boolean)
5
+ .join("\n\n");
6
+ }
7
+ export function loadContextDelta(previous, current) {
8
+ const known = new Set(previous.split("\n"));
9
+ return current
10
+ .split("\n")
11
+ .filter((line) => line && !known.has(line))
12
+ .join("\n");
13
+ }
@@ -0,0 +1,9 @@
1
+ import type { FileSystem } from "./types.js";
2
+ export declare const CONTEXT_LAYERS: readonly ["global", "project", "task", "session"];
3
+ export type ContextLayer = (typeof CONTEXT_LAYERS)[number];
4
+ export type ContextStore = {
5
+ layers: Record<ContextLayer, string>;
6
+ };
7
+ export declare function readContextStore(root: string, fs: FileSystem): ContextStore;
8
+ export declare function writeContextLayer(root: string, fs: FileSystem, layer: ContextLayer, content: string): void;
9
+ export declare function composeContext(store: ContextStore): string;
@@ -0,0 +1,18 @@
1
+ import { join } from "node:path";
2
+ export const CONTEXT_LAYERS = ["global", "project", "task", "session"];
3
+ export function readContextStore(root, fs) {
4
+ const layers = Object.fromEntries(CONTEXT_LAYERS.map((layer) => {
5
+ const path = join(root, ".aiw/context", `${layer}.md`);
6
+ return [layer, fs.exists(path) ? fs.read(path) : ""];
7
+ }));
8
+ return { layers };
9
+ }
10
+ export function writeContextLayer(root, fs, layer, content) {
11
+ fs.mkdir(join(root, ".aiw/context"));
12
+ fs.write(join(root, ".aiw/context", `${layer}.md`), content.endsWith("\n") ? content : `${content}\n`);
13
+ }
14
+ export function composeContext(store) {
15
+ return CONTEXT_LAYERS.filter((layer) => store.layers[layer].trim())
16
+ .map((layer) => `# ${layer} context\n\n${store.layers[layer].trim()}`)
17
+ .join("\n\n");
18
+ }
@@ -0,0 +1,9 @@
1
+ import type { ResourceType } from "./package-contract.js";
2
+ import type { FileSystem } from "./types.js";
3
+ export type CopilotResourceType = ResourceType | "context";
4
+ export type CopilotResourceDescriptor = {
5
+ path: string;
6
+ support: "native" | "compatibility";
7
+ };
8
+ export declare function describeCopilotResource(type: CopilotResourceType, id: string): CopilotResourceDescriptor;
9
+ export declare function renderCopilotContext(root: string, content: string, fs: FileSystem): string;
@@ -0,0 +1,24 @@
1
+ import { join } from "node:path";
2
+ export function describeCopilotResource(type, id) {
3
+ if (type === "skills")
4
+ return { path: `.github/skills/${id}/SKILL.md`, support: "native" };
5
+ if (type === "rules")
6
+ return { path: `.github/instructions/${id}.instructions.md`, support: "native" };
7
+ if (type === "agents")
8
+ return { path: `.github/agents/${id}.md`, support: "native" };
9
+ if (type === "context")
10
+ return { path: ".github/copilot-instructions.md", support: "native" };
11
+ const roots = {
12
+ hooks: ".github/aiw/hooks",
13
+ templates: ".github/aiw/templates",
14
+ };
15
+ const root = roots[type];
16
+ if (!root)
17
+ throw new Error(`Unsupported Copilot resource type: ${type}`);
18
+ return { path: `${root}/${id}.md`, support: "compatibility" };
19
+ }
20
+ export function renderCopilotContext(root, content, fs) {
21
+ const path = describeCopilotResource("context", "project").path;
22
+ fs.write(join(root, path), content);
23
+ return path;
24
+ }
@@ -0,0 +1,9 @@
1
+ import type { ResourceType } from "./package-contract.js";
2
+ import type { FileSystem } from "./types.js";
3
+ export type CursorResourceType = ResourceType | "context";
4
+ export type CursorResourceDescriptor = {
5
+ path: string;
6
+ support: "native" | "compatibility";
7
+ };
8
+ export declare function describeCursorResource(type: CursorResourceType, id: string): CursorResourceDescriptor;
9
+ export declare function renderCursorContext(root: string, content: string, fs: FileSystem): string;
@@ -0,0 +1,25 @@
1
+ import { join } from "node:path";
2
+ export function describeCursorResource(type, id) {
3
+ if (type === "rules")
4
+ return { path: `.cursor/rules/${id}.mdc`, support: "native" };
5
+ if (type === "context")
6
+ return { path: "AGENTS.md", support: "native" };
7
+ const roots = {
8
+ skills: ".cursor/skills",
9
+ agents: ".cursor/aiw/agents",
10
+ hooks: ".cursor/aiw/hooks",
11
+ templates: ".cursor/aiw/templates",
12
+ };
13
+ const root = roots[type];
14
+ if (!root)
15
+ throw new Error(`Unsupported Cursor resource type: ${type}`);
16
+ return {
17
+ path: type === "skills" ? `${root}/${id}/SKILL.md` : `${root}/${id}.md`,
18
+ support: "compatibility",
19
+ };
20
+ }
21
+ export function renderCursorContext(root, content, fs) {
22
+ const path = describeCursorResource("context", "project").path;
23
+ fs.write(join(root, path), content);
24
+ return path;
25
+ }
@@ -0,0 +1,37 @@
1
+ import type { FileSystem } from "./types.js";
2
+ export type DashboardFact = {
3
+ key: string;
4
+ value: string;
5
+ state: string;
6
+ confidence: string;
7
+ };
8
+ export type DashboardRecommendation = {
9
+ id: string;
10
+ provider: string;
11
+ selected: boolean;
12
+ };
13
+ export type DashboardTrace = {
14
+ requirement: string;
15
+ decisions: string[];
16
+ tasks: string[];
17
+ evidence: string[];
18
+ };
19
+ export type DashboardModel = {
20
+ project: string;
21
+ target: string;
22
+ facts: DashboardFact[];
23
+ recommendations: DashboardRecommendation[];
24
+ traceability: DashboardTrace[];
25
+ };
26
+ export type DashboardCommand = (args: string[]) => Promise<{
27
+ exitCode: number;
28
+ output?: string;
29
+ error?: string;
30
+ }>;
31
+ export type DashboardHandle = {
32
+ url: string;
33
+ close(): Promise<void>;
34
+ };
35
+ export declare function buildDashboardModel(root: string, fs: FileSystem): DashboardModel;
36
+ export declare function renderDashboard(model: DashboardModel, notice?: string): string;
37
+ export declare function startDashboard(root: string, fs: FileSystem, execute: DashboardCommand, port?: number): Promise<DashboardHandle>;