@felixdotgo/aidlc-kit 0.1.1 → 0.2.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 (134) hide show
  1. package/DEVELOPMENT.md +14 -0
  2. package/README.md +11 -13
  3. package/dist/assets/.agents/aidlc/docker/Dockerfile.claude +7 -0
  4. package/dist/assets/.agents/aidlc/docker/Dockerfile.codex +9 -0
  5. package/dist/assets/.agents/aidlc/docker/Dockerfile.opencode +8 -0
  6. package/dist/assets/.agents/aidlc/orchestrator.md +1 -1
  7. package/dist/assets/.agents/aidlc/phase-clarify.md +1 -1
  8. package/dist/assets/.agents/aidlc/phase-plan.md +2 -2
  9. package/dist/assets/.agents/aidlc/schemas/config.schema.json +2 -1
  10. package/dist/assets/.agents/aidlc/scripts/lib/loop-authority.mjs +245 -0
  11. package/dist/assets/.agents/aidlc/scripts/lib/loop-commit-message.mjs +45 -0
  12. package/dist/assets/.agents/aidlc/scripts/lib/loop-daemon.mjs +232 -0
  13. package/dist/assets/.agents/aidlc/scripts/lib/loop-drivers.mjs +15 -3
  14. package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-cli.mjs +86 -28
  15. package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-remote.mjs +7 -0
  16. package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet-supervisor.mjs +22 -6
  17. package/dist/assets/.agents/aidlc/scripts/lib/loop-fleet.mjs +40 -15
  18. package/dist/assets/.agents/aidlc/scripts/lib/loop-git.mjs +14 -6
  19. package/dist/assets/.agents/aidlc/scripts/lib/loop-intake.mjs +23 -5
  20. package/dist/assets/.agents/aidlc/scripts/lib/loop-local-workers.mjs +42 -15
  21. package/dist/assets/.agents/aidlc/scripts/lib/loop-runtime.mjs +75 -5
  22. package/dist/assets/.agents/aidlc/scripts/lib/loop-stream.mjs +60 -0
  23. package/dist/assets/.agents/aidlc/scripts/lib/loop-supervisor-run-local.mjs +142 -5
  24. package/dist/assets/.agents/aidlc/scripts/lib/loop-supervisor.mjs +9 -1
  25. package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-docker.mjs +31 -5
  26. package/dist/assets/.agents/aidlc/scripts/lib/loop-worker-image.mjs +64 -0
  27. package/dist/assets/.agents/aidlc/scripts/lib/store.mjs +57 -2
  28. package/dist/assets/.agents/aidlc/scripts/loop-entry.mjs +85 -73
  29. package/dist/assets/.agents/aidlc/scripts/loop-gate.mjs +19 -7
  30. package/dist/assets/.agents/aidlc/scripts/loop.mjs +2 -1
  31. package/dist/assets/.agents/aidlc/templates/design.md +9 -0
  32. package/dist/assets/.agents/aidlc/templates/intent.md +4 -0
  33. package/dist/assets/.agents/aidlc/templates/workplan.md +1 -1
  34. package/dist/assets/.agents/skills/aidlc-plan/SKILL.md +1 -1
  35. package/dist/assets/ui/bulma.min.css +3 -0
  36. package/dist/assets/ui/dashboard.css +414 -0
  37. package/dist/services/aidlc-coordination/Dockerfile +11 -3
  38. package/dist/services/aidlc-coordination/compose.yaml +12 -0
  39. package/dist/services/aidlc-coordination/package-lock.json +3 -1
  40. package/dist/services/aidlc-coordination/package.json +9 -4
  41. package/dist/services/aidlc-coordination/src/lifecycle-core.mjs +57 -2
  42. package/dist/services/aidlc-coordination/src/repository.mjs +66 -0
  43. package/dist/services/aidlc-coordination/src/server.mjs +9 -3
  44. package/dist/services/aidlc-coordination/test/fleet.test.mjs +21 -0
  45. package/dist/services/aidlc-coordination/test/server-health-auth.test.mjs +67 -0
  46. package/dist/src/adapters.d.ts +0 -3
  47. package/dist/src/adapters.js +3 -5
  48. package/dist/src/cli/argv.d.ts +12 -0
  49. package/dist/src/cli/argv.js +62 -0
  50. package/dist/src/cli/commands.d.ts +8 -0
  51. package/dist/src/cli/commands.js +129 -0
  52. package/dist/src/cli/options.d.ts +25 -0
  53. package/dist/src/cli/options.js +32 -0
  54. package/dist/src/cli/prompt.d.ts +9 -0
  55. package/dist/src/cli/prompt.js +66 -0
  56. package/dist/src/cli.js +25 -191
  57. package/dist/src/gate.js +3 -2
  58. package/dist/src/installer.d.ts +14 -7
  59. package/dist/src/installer.js +38 -141
  60. package/dist/src/legacy.js +1 -0
  61. package/dist/src/managed-content.d.ts +7 -0
  62. package/dist/src/managed-content.js +15 -4
  63. package/dist/src/managed-planning.d.ts +65 -0
  64. package/dist/src/managed-planning.js +219 -0
  65. package/dist/src/mcp-setup.js +3 -1
  66. package/dist/src/model/config-contracts.d.ts +65 -0
  67. package/dist/src/model/config-contracts.js +1 -0
  68. package/dist/src/model/install-contracts.d.ts +29 -0
  69. package/dist/src/model/install-contracts.js +1 -0
  70. package/dist/src/model/lifecycle-enums.d.ts +13 -0
  71. package/dist/src/model/lifecycle-enums.js +1 -0
  72. package/dist/src/model/loop.d.ts +20 -0
  73. package/dist/src/model/loop.js +1 -0
  74. package/dist/src/model/manifest.d.ts +16 -0
  75. package/dist/src/model/manifest.js +1 -0
  76. package/dist/src/model/records.d.ts +138 -0
  77. package/dist/src/model/records.js +1 -0
  78. package/dist/src/model.d.ts +11 -264
  79. package/dist/src/model.js +1 -1
  80. package/dist/src/profiles.d.ts +2 -0
  81. package/dist/src/profiles.js +53 -9
  82. package/dist/src/state/archive-record.d.ts +9 -0
  83. package/dist/src/state/archive-record.js +26 -0
  84. package/dist/src/state/commands.d.ts +18 -0
  85. package/dist/src/state/commands.js +27 -0
  86. package/dist/src/state/domain.d.ts +9 -0
  87. package/dist/src/state/domain.js +9 -0
  88. package/dist/src/state/guards.d.ts +7 -0
  89. package/dist/src/state/guards.js +17 -0
  90. package/dist/src/state/io.d.ts +10 -0
  91. package/dist/src/state/io.js +35 -0
  92. package/dist/src/state/items.d.ts +3 -4
  93. package/dist/src/state/items.js +58 -57
  94. package/dist/src/state/lessons.js +14 -7
  95. package/dist/src/state/lifecycle.js +2 -2
  96. package/dist/src/state/lock.js +7 -6
  97. package/dist/src/state/memory.js +24 -12
  98. package/dist/src/state/{archive.js → migrate.js} +7 -7
  99. package/dist/src/state/partition.d.ts +15 -0
  100. package/dist/src/state/partition.js +90 -0
  101. package/dist/src/state/paths.d.ts +11 -0
  102. package/dist/src/state/paths.js +12 -0
  103. package/dist/src/state/render.js +9 -6
  104. package/dist/src/state/store.js +9 -15
  105. package/dist/src/state/transitions.js +9 -7
  106. package/dist/src/state/validate.js +50 -7
  107. package/dist/src/state.d.ts +16 -11
  108. package/dist/src/state.js +16 -11
  109. package/dist/src/task-ui.d.ts +54 -0
  110. package/dist/src/task-ui.js +1570 -0
  111. package/dist/src/upgrade-board.js +10 -10
  112. package/dist/src/upgrade.d.ts +0 -1
  113. package/dist/src/upgrade.js +19 -83
  114. package/dist/src/workflow.js +3 -3
  115. package/docs/README.md +6 -2
  116. package/docs/architecture.md +9 -8
  117. package/docs/command-reference.md +81 -20
  118. package/docs/configuration.md +28 -8
  119. package/docs/coordination-service.md +18 -6
  120. package/docs/design-decisions.md +83 -0
  121. package/docs/development.md +27 -2
  122. package/docs/loop-local-run.md +495 -0
  123. package/docs/loop-runbook.md +235 -0
  124. package/docs/operating-workflow.md +2 -2
  125. package/docs/testing-and-release.md +5 -1
  126. package/docs/troubleshooting.md +125 -0
  127. package/package.json +4 -1
  128. package/dist/src/ledger.d.ts +0 -22
  129. package/dist/src/ledger.js +0 -119
  130. package/dist/src/state/shared.d.ts +0 -29
  131. package/dist/src/state/shared.js +0 -71
  132. package/dist/src/tracker.d.ts +0 -36
  133. package/dist/src/tracker.js +0 -44
  134. /package/dist/src/state/{archive.d.ts → migrate.d.ts} +0 -0
@@ -1,71 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
3
- import { dirname, isAbsolute, join, normalize, resolve } from "node:path";
4
- import { resolveProjectPathWithoutSymlinks } from "../project-path.js";
5
- export const statePath = (root) => join(resolve(root), ".agents/data/state/aidlc-state.json");
6
- export const lessonIndexPath = (root) => join(resolve(root), ".agents/data/lessons/index.json");
7
- export const memoryRegistryPath = (root) => join(resolve(root), ".agents/data/memory/agentic-memory.json");
8
- export const stateLockPath = (root) => join(resolve(root), ".agents/data/state/.aidlc-state.lock");
9
- export const stateLockGuardPath = (root) => join(resolve(root), ".agents/data/state/.aidlc-state.lock.guard");
10
- export const emptyState = () => ({ schemaVersion: 4, tasks: {}, archive: {} });
11
- export const legacyG2WaitSource = "schema-v4-migration";
12
- export const phases = ["clarify", "plan", "build", "wrap", "done"];
13
- export const gates = ["none", "G0_confirm", "G1_review", "G2_codereview"];
14
- export const handoffKinds = ["repair_exhausted", "review_exhausted", "g2_failed", "release_failed", "structural_change", "other"];
15
- export const terminal = (task) => task.status === "done" || task.status === "closed" || task.status === "superseded";
16
- export const phaseGate = (phase) => phase === "clarify" ? "G0_confirm" : phase === "plan" ? "G1_review" : phase === "build" ? "G2_codereview" : "none";
17
- export const iso = (value) => typeof value === "string" && Number.isFinite(Date.parse(value)) && new Date(Date.parse(value)).toISOString() === value;
18
- export const text = (value) => typeof value === "string" && Boolean(value.trim());
19
- export const idPattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
20
- export const digest = (content) => createHash("sha256").update(content).digest("hex");
21
- export const archiveRecordPath = (id) => `.agents/data/state/archive/${id}.json`;
22
- export const taskRecordContent = (task) => `${JSON.stringify(task, null, 2)}\n`;
23
- export const assertNoSymlinkPath = (root, relative) => {
24
- resolveProjectPathWithoutSymlinks(root, relative, "Unsafe state path", "State path crosses a symlink");
25
- };
26
- export const writeAtomic = (path, content) => {
27
- mkdirSync(dirname(path), { recursive: true });
28
- const temporary = `${path}.tmp-${process.pid}-${Date.now()}`;
29
- writeFileSync(temporary, content, "utf8");
30
- renameSync(temporary, path);
31
- };
32
- export const parseJsonText = (content, label, recovery = "") => {
33
- try {
34
- return JSON.parse(content);
35
- }
36
- catch (error) {
37
- throw new Error(`${label} is corrupted or unreadable: ${error instanceof Error ? error.message : String(error)}${recovery ? `; ${recovery}` : ""}`);
38
- }
39
- };
40
- export const parseJsonFile = (path, label, recovery = "") => parseJsonText(readFileSync(path, "utf8"), label, recovery);
41
- export const audited = (reason, source) => {
42
- if (!text(reason) || !text(source))
43
- throw new Error("Lifecycle mutation requires non-empty --reason and --source");
44
- };
45
- export const tokens = (value) => [...new Set(value.toLocaleLowerCase().split(/[^\p{L}\p{N}]+/u).filter((item) => item.length > 1))];
46
- /** Rejects artifact paths that escape the project-owned tasks directory. */
47
- export const assertTaskArtifactPath = (id, path) => {
48
- const separator = process.platform === "win32" ? "\\" : "/";
49
- const cleaned = normalize(path);
50
- if (isAbsolute(cleaned) || cleaned === ".." || cleaned.startsWith(`..${separator}`) || !cleaned.startsWith(`.agents${separator}data${separator}tasks${separator}`)) {
51
- throw new Error(`Invalid artifact path for ${id}: ${path}`);
52
- }
53
- };
54
- /** Builds the immutable archive-catalog summary for a terminal task from its record content. */
55
- export const archivedSummary = (task, content = taskRecordContent(task)) => ({
56
- id: task.id,
57
- title: task.title,
58
- type: task.type,
59
- phase: task.phase,
60
- gate: task.gate,
61
- status: task.status,
62
- risk: task.risk,
63
- areas: task.areas,
64
- record: archiveRecordPath(task.id),
65
- digest: digest(content),
66
- lessonCount: task.lessons?.length ?? 0,
67
- predecessorTaskId: task.predecessorTaskId,
68
- successorTaskId: task.successorTaskId,
69
- createdAt: task.createdAt,
70
- updatedAt: task.updatedAt
71
- });
@@ -1,36 +0,0 @@
1
- /**
2
- * Backlog tracker integration: resolves tracker credentials from the environment
3
- * and builds the HTTP requests used to mirror lifecycle phase transitions.
4
- */
5
- import type { TrackerConfig } from "./model.js";
6
- export interface TrackerDiagnostic {
7
- code: "TRACKER_DISABLED" | "TRACKER_AUTH" | "TRACKER_RATE_LIMIT" | "TRACKER_REQUEST";
8
- message: string;
9
- retryable: boolean;
10
- }
11
- export interface BacklogRequest {
12
- method: "GET" | "PATCH";
13
- path: string;
14
- form?: Record<string, string | number>;
15
- }
16
- export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
17
- export type TrackerResolution = {
18
- enabled: false;
19
- diagnostic: TrackerDiagnostic;
20
- } | {
21
- enabled: true;
22
- config: TrackerConfig;
23
- token: string;
24
- };
25
- /** Resolves a tracker configuration into either an enabled resolution (with token) or a disabled diagnostic. */
26
- export declare const resolveTracker: (config: TrackerConfig | undefined, environment?: NodeJS.ProcessEnv) => TrackerResolution;
27
- /** Executes a single Backlog request, mapping HTTP failures to retryable diagnostics. */
28
- export declare const executeBacklog: (resolution: TrackerResolution, request: BacklogRequest, fetcher?: FetchLike) => Promise<{
29
- ok: true;
30
- body: unknown;
31
- } | {
32
- ok: false;
33
- diagnostic: TrackerDiagnostic;
34
- }>;
35
- /** Builds the Backlog PATCH request that mirrors a lifecycle phase transition for an issue. */
36
- export declare const gateUpdate: (config: TrackerConfig, issue: string, phase: "clarify" | "plan" | "build" | "wrap" | "done", idempotencyKey: string) => BacklogRequest;
@@ -1,44 +0,0 @@
1
- /** Resolves a tracker configuration into either an enabled resolution (with token) or a disabled diagnostic. */
2
- export const resolveTracker = (config, environment = process.env) => {
3
- if (!config)
4
- return { enabled: false, diagnostic: { code: "TRACKER_DISABLED", message: "Tracker is not configured; Git-only mode is active.", retryable: false } };
5
- const token = environment[config.tokenEnv];
6
- if (!token)
7
- return { enabled: false, diagnostic: { code: "TRACKER_DISABLED", message: `Backlog tracker is disabled because ${config.tokenEnv} is unavailable.`, retryable: false } };
8
- return { enabled: true, config, token };
9
- };
10
- const form = (values) => {
11
- const body = new URLSearchParams();
12
- for (const [key, value] of Object.entries(values))
13
- body.set(key, String(value));
14
- return body;
15
- };
16
- /** Executes a single Backlog request, mapping HTTP failures to retryable diagnostics. */
17
- export const executeBacklog = async (resolution, request, fetcher = fetch) => {
18
- if (!resolution.enabled)
19
- return { ok: false, diagnostic: resolution.diagnostic };
20
- const response = await fetcher(`${resolution.config.spaceUrl}/api/v2/${request.path.replace(/^\//, "")}`, {
21
- method: request.method,
22
- headers: { Authorization: `Bearer ${resolution.token}`, ...(request.form ? { "Content-Type": "application/x-www-form-urlencoded" } : {}) },
23
- body: request.form ? form(request.form) : undefined
24
- });
25
- if (response.status === 401)
26
- return { ok: false, diagnostic: { code: "TRACKER_AUTH", message: "Backlog authentication failed; Git state was not changed.", retryable: false } };
27
- if (response.status === 429)
28
- return { ok: false, diagnostic: { code: "TRACKER_RATE_LIMIT", message: "Backlog rate limit reached; retry after the provider reset window.", retryable: true } };
29
- if (!response.ok)
30
- return { ok: false, diagnostic: { code: "TRACKER_REQUEST", message: `Backlog request failed with HTTP ${response.status}.`, retryable: response.status >= 500 } };
31
- return { ok: true, body: await response.json() };
32
- };
33
- /** Builds the Backlog PATCH request that mirrors a lifecycle phase transition for an issue. */
34
- export const gateUpdate = (config, issue, phase, idempotencyKey) => {
35
- const comment = `[aidlc:${idempotencyKey}] ${phase}`;
36
- if (config.workflow === "waterfall") {
37
- const statusId = config.mapping.statuses?.[phase];
38
- if (!statusId)
39
- throw new Error(`Backlog status mapping is required for Waterfall phase: ${phase}`);
40
- return { method: "PATCH", path: `issues/${issue}`, form: { statusId, comment } };
41
- }
42
- const field = config.mapping.gateFieldId;
43
- return { method: "PATCH", path: `issues/${issue}`, form: { ...(field ? { [`customField_${field}`]: phase } : {}), comment } };
44
- };
File without changes