ahead-pi 0.2.0 → 0.3.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/README.md +29 -9
- package/dist/ahead_wasm.wasm +0 -0
- package/generated/corrective-debugging/ai-audit.md +39 -0
- package/generated/corrective-debugging/ai-review.md +46 -0
- package/generated/corrective-debugging/characterize.md +53 -0
- package/generated/corrective-debugging/conclude.md +59 -0
- package/generated/corrective-debugging/correction.md +53 -0
- package/generated/corrective-debugging/deploy.md +38 -0
- package/generated/corrective-debugging/human-review.md +45 -0
- package/generated/corrective-debugging/implement.md +42 -0
- package/generated/corrective-debugging/investigate.md +59 -0
- package/generated/corrective-debugging/manifest.json +30 -0
- package/generated/corrective-debugging/model.md +53 -0
- package/generated/corrective-debugging/outcome.md +38 -0
- package/generated/corrective-debugging/plan.md +53 -0
- package/generated/corrective-debugging/verify.md +47 -0
- package/generated/decision/compare.md +45 -0
- package/generated/decision/criteria.md +45 -0
- package/generated/decision/decide.md +45 -0
- package/generated/decision/frame.md +45 -0
- package/generated/decision/manifest.json +21 -0
- package/generated/decision/options.md +47 -0
- package/generated/decision/publish.md +38 -0
- package/generated/decision/research.md +45 -0
- package/generated/internal-improvement/ai-audit.md +39 -0
- package/generated/internal-improvement/ai-review.md +46 -0
- package/generated/internal-improvement/baseline.md +46 -0
- package/generated/internal-improvement/decision.md +45 -0
- package/generated/internal-improvement/deploy.md +38 -0
- package/generated/internal-improvement/human-review.md +45 -0
- package/generated/internal-improvement/implement.md +42 -0
- package/generated/internal-improvement/invariants.md +38 -0
- package/generated/internal-improvement/manifest.json +29 -0
- package/generated/internal-improvement/options.md +47 -0
- package/generated/internal-improvement/outcome.md +38 -0
- package/generated/internal-improvement/plan.md +53 -0
- package/generated/internal-improvement/target.md +45 -0
- package/generated/internal-improvement/verify.md +45 -0
- package/generated/investigation/bound.md +45 -0
- package/generated/investigation/conclude.md +45 -0
- package/generated/investigation/explore.md +60 -0
- package/generated/investigation/frame.md +45 -0
- package/generated/investigation/gather.md +45 -0
- package/generated/investigation/manifest.json +21 -0
- package/generated/investigation/synthesize.md +51 -0
- package/generated/operational-stabilization/assess.md +46 -0
- package/generated/operational-stabilization/execute-observe.md +45 -0
- package/generated/operational-stabilization/manifest.json +19 -0
- package/generated/operational-stabilization/monitor.md +45 -0
- package/generated/operational-stabilization/outcome.md +38 -0
- package/generated/operational-stabilization/respond.md +40 -0
- package/generated/operational-stabilization/verify-recovery.md +45 -0
- package/generated/product-change/ai-audit.md +12 -6
- package/generated/product-change/ai-review.md +20 -7
- package/generated/product-change/decision.md +16 -4
- package/generated/product-change/define.md +9 -4
- package/generated/product-change/deploy.md +9 -4
- package/generated/product-change/human-review.md +16 -4
- package/generated/product-change/implement.md +14 -5
- package/generated/product-change/manifest.json +9 -4
- package/generated/product-change/options.md +16 -4
- package/generated/product-change/outcome.md +9 -4
- package/generated/product-change/plan.md +22 -4
- package/generated/product-change/questions.md +22 -4
- package/generated/product-change/research.md +16 -4
- package/generated/product-change/verify.md +9 -4
- package/generated/recommended-skills.json +24 -0
- package/generated/reference/CONSTITUTION.md +43 -0
- package/generated/reference/docs/acceptable-ai-use.md +217 -0
- package/generated/reference/docs/design/adapted-skill-guidance.md +27 -0
- package/generated/reference/docs/design/debugging-and-operations.md +119 -0
- package/generated/reference/docs/design/executable-workflows.md +122 -0
- package/generated/reference/docs/design/instruction-authoring.md +28 -0
- package/generated/reference/docs/design/process-taxonomy.md +144 -0
- package/generated/reference/docs/design/review-workbench.md +37 -0
- package/generated/reference/docs/engineering-practice.md +163 -0
- package/generated/reference/docs/evidence/evidence-standard.md +123 -0
- package/generated/reference/docs/evidence/research-map.md +98 -0
- package/generated/reference/docs/rationale.md +210 -0
- package/generated/reference/docs/recommended-skills.md +19 -0
- package/generated/reference/docs/references/pragmatic-programmer-page-index.md +113 -0
- package/generated/reference/docs/references/submitted-engineering-notes.md +306 -0
- package/generated/reference/docs/releasing-pi.md +89 -0
- package/generated/reference/docs/workflows/README.md +142 -0
- package/generated/reference/docs/workflows/corrective-debugging.md +221 -0
- package/generated/reference/docs/workflows/decision.md +149 -0
- package/generated/reference/docs/workflows/internal-improvement.md +219 -0
- package/generated/reference/docs/workflows/investigation.md +161 -0
- package/generated/reference/docs/workflows/operational-stabilization.md +187 -0
- package/generated/reference/docs/workflows/product-change.md +216 -0
- package/generated/reference/index.json +298 -0
- package/package.json +36 -25
- package/src/engine.ts +26 -7
- package/src/flow-guides.ts +168 -0
- package/src/guidance.ts +220 -72
- package/src/index.ts +696 -140
- package/src/reference-viewer.ts +73 -0
- package/src/reference.ts +107 -0
- package/src/review.ts +360 -0
- package/src/skills.ts +133 -0
- package/src/storage.ts +77 -13
- package/src/types.ts +1 -0
package/src/storage.ts
CHANGED
|
@@ -11,9 +11,11 @@ interface CurrentRunPointer {
|
|
|
11
11
|
|
|
12
12
|
export class RunStore {
|
|
13
13
|
readonly aheadDirectory: string;
|
|
14
|
+
readonly projectRoot: string;
|
|
14
15
|
|
|
15
|
-
constructor(
|
|
16
|
-
this.
|
|
16
|
+
constructor(rootPath: string) {
|
|
17
|
+
this.projectRoot = rootPath;
|
|
18
|
+
this.aheadDirectory = join(rootPath, ".ahead");
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
newRunId(): string {
|
|
@@ -23,19 +25,20 @@ export class RunStore {
|
|
|
23
25
|
|
|
24
26
|
async loadCurrent(): Promise<Run | undefined> {
|
|
25
27
|
try {
|
|
26
|
-
const pointer =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
28
|
+
const pointer = parseCurrentRunPointer(
|
|
29
|
+
await readFile(join(this.aheadDirectory, "current.json"), "utf8"),
|
|
30
|
+
);
|
|
30
31
|
return this.load(pointer.run_id);
|
|
31
32
|
} catch (error) {
|
|
32
|
-
if (isMissing(error))
|
|
33
|
+
if (isMissing(error)) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
33
36
|
throw error;
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
async load(runId: string): Promise<Run> {
|
|
38
|
-
return
|
|
41
|
+
return parseRun(await readFile(this.runPath(runId), "utf8"));
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
async save(run: Run, makeCurrent = true): Promise<void> {
|
|
@@ -48,7 +51,13 @@ export class RunStore {
|
|
|
48
51
|
|
|
49
52
|
artifactPath(run: Run, phase: string, kind: string): { absolute: string; relative: string } {
|
|
50
53
|
const sequence = String(run.events.length + 1).padStart(4, "0");
|
|
51
|
-
const absolute = join(
|
|
54
|
+
const absolute = join(
|
|
55
|
+
this.aheadDirectory,
|
|
56
|
+
"runs",
|
|
57
|
+
run.id,
|
|
58
|
+
"artifacts",
|
|
59
|
+
`${sequence}-${phase}-${kind}.md`,
|
|
60
|
+
);
|
|
52
61
|
return { absolute, relative: relative(this.projectRoot, absolute) };
|
|
53
62
|
}
|
|
54
63
|
|
|
@@ -62,15 +71,28 @@ export class RunStore {
|
|
|
62
71
|
await writeFile(resolved, `${content.trim()}\n`, { encoding: "utf8", flag: "wx" });
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
async readArtifact(path: string): Promise<string> {
|
|
75
|
+
const resolved = resolve(this.projectRoot, path);
|
|
76
|
+
const artifactsRoot = resolve(this.aheadDirectory, "runs");
|
|
77
|
+
if (!resolved.startsWith(`${artifactsRoot}/`)) {
|
|
78
|
+
throw new Error("artifact path escaped .ahead/runs");
|
|
79
|
+
}
|
|
80
|
+
return readFile(resolved, "utf8");
|
|
81
|
+
}
|
|
82
|
+
|
|
65
83
|
private runPath(runId: string): string {
|
|
66
|
-
if (!/^[A-Za-z0-9._-]+$/.test(runId))
|
|
84
|
+
if (!/^[A-Za-z0-9._-]+$/.test(runId)) {
|
|
85
|
+
throw new Error("unsafe AHEAD run id");
|
|
86
|
+
}
|
|
67
87
|
return join(this.aheadDirectory, "runs", runId, "run.json");
|
|
68
88
|
}
|
|
69
89
|
}
|
|
70
90
|
|
|
71
91
|
export function humanActor(cwd: string): Actor {
|
|
72
92
|
const explicit = process.env.AHEAD_HUMAN_IDENTITY?.trim();
|
|
73
|
-
if (explicit)
|
|
93
|
+
if (explicit) {
|
|
94
|
+
return { kind: "human", identity: explicit };
|
|
95
|
+
}
|
|
74
96
|
for (const key of ["user.email", "user.name"]) {
|
|
75
97
|
try {
|
|
76
98
|
const value = execFileSync("git", ["config", key], {
|
|
@@ -78,7 +100,9 @@ export function humanActor(cwd: string): Actor {
|
|
|
78
100
|
encoding: "utf8",
|
|
79
101
|
stdio: ["ignore", "pipe", "ignore"],
|
|
80
102
|
}).trim();
|
|
81
|
-
if (value)
|
|
103
|
+
if (value) {
|
|
104
|
+
return { kind: "human", identity: value };
|
|
105
|
+
}
|
|
82
106
|
} catch {
|
|
83
107
|
// Fall through to the next local identity source.
|
|
84
108
|
}
|
|
@@ -93,7 +117,9 @@ export function projectRoot(cwd: string): string {
|
|
|
93
117
|
encoding: "utf8",
|
|
94
118
|
stdio: ["ignore", "pipe", "ignore"],
|
|
95
119
|
}).trim();
|
|
96
|
-
if (root)
|
|
120
|
+
if (root) {
|
|
121
|
+
return root;
|
|
122
|
+
}
|
|
97
123
|
} catch {
|
|
98
124
|
// AHEAD can also persist beside work that is not yet in Git.
|
|
99
125
|
}
|
|
@@ -110,3 +136,41 @@ async function atomicJson(path: string, value: unknown): Promise<void> {
|
|
|
110
136
|
function isMissing(error: unknown): boolean {
|
|
111
137
|
return !!error && typeof error === "object" && "code" in error && error.code === "ENOENT";
|
|
112
138
|
}
|
|
139
|
+
|
|
140
|
+
function parseCurrentRunPointer(content: string): CurrentRunPointer {
|
|
141
|
+
const value: unknown = JSON.parse(content);
|
|
142
|
+
if (
|
|
143
|
+
!isRecord(value) ||
|
|
144
|
+
value.api_version !== "ahead.current/v0" ||
|
|
145
|
+
typeof value.run_id !== "string" ||
|
|
146
|
+
value.run_id.length === 0
|
|
147
|
+
) {
|
|
148
|
+
throw new Error("invalid .ahead/current.json");
|
|
149
|
+
}
|
|
150
|
+
return { api_version: value.api_version, run_id: value.run_id };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function parseRun(content: string): Run {
|
|
154
|
+
const value: unknown = JSON.parse(content);
|
|
155
|
+
if (!isRun(value)) {
|
|
156
|
+
throw new Error("invalid AHEAD run record");
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function isRun(value: unknown): value is Run {
|
|
162
|
+
return (
|
|
163
|
+
isRecord(value) &&
|
|
164
|
+
typeof value.api_version === "string" &&
|
|
165
|
+
typeof value.id === "string" &&
|
|
166
|
+
typeof value.title === "string" &&
|
|
167
|
+
typeof value.workflow_id === "string" &&
|
|
168
|
+
typeof value.workflow_version === "string" &&
|
|
169
|
+
typeof value.owner === "string" &&
|
|
170
|
+
Array.isArray(value.events)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
175
|
+
return typeof value === "object" && value !== null;
|
|
176
|
+
}
|