paqad-ai 1.44.0 → 1.46.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/CHANGELOG.md +35 -0
- package/dist/cli/index.js +282 -23
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +34 -8
- package/dist/index.js.map +1 -1
- package/dist/kernel/gate.d.ts +5 -0
- package/dist/kernel/gate.js +634 -84
- package/dist/kernel/gate.js.map +1 -1
- package/dist/stage-evidence/live-writer.js +5 -3
- package/dist/stage-evidence/live-writer.js.map +1 -1
- package/dist/stage-evidence/marker-parse.d.ts +5 -3
- package/dist/stage-evidence/marker-parse.js +10 -8
- package/dist/stage-evidence/marker-parse.js.map +1 -1
- package/dist/stage-evidence/narration.d.ts +14 -1
- package/dist/stage-evidence/narration.js +15 -0
- package/dist/stage-evidence/narration.js.map +1 -1
- package/package.json +1 -1
- package/runtime/AGENT-BOOTSTRAP.md +3 -3
- package/runtime/base/skills/decision/SKILL.md +1 -1
- package/runtime/base/skills/decision/references/decision-packet-contract.md +1 -1
- package/runtime/hooks/agent-entry-gate.mjs +49 -2
- package/runtime/hooks/capability-gate.mjs +56 -15
- package/runtime/hooks/lib/loop-guard.mjs +32 -0
- package/runtime/hooks/stage-marker-parse.mjs +12 -2
- package/runtime/hooks/verification-completion.mjs +11 -1
- package/runtime/scripts/verify-backstop.mjs +15 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# paqad-ai
|
|
2
2
|
|
|
3
|
+
## 1.46.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 944f52f: Stages gate: same-turn unblock that actually works, sentinel bootstrap un-deadlocked, and stage narration everywhere (#307).
|
|
8
|
+
|
|
9
|
+
- `paqad:stage` markers are now parsed at the pre-mutation seam too, so markers emitted earlier in the same turn clear the block-forward gate immediately — not only after Stop.
|
|
10
|
+
- New `paqad-ai stage <start|end> <stage>` CLI verb replaces the never-shipped `scripts/se-mark.ts` as the shell escape hatch; the block message, framework bootstrap, and decision-skill docs now name only remediations that exist on an onboarded project.
|
|
11
|
+
- The write of `.paqad/.agent-entry-loaded` is exempt from both the agent-entry gate and the stages gate: turn one can complete the bootstrap it is being asked to perform.
|
|
12
|
+
- Narration and ledger are both non-negotiable: every stage-evidence row minted from markers (pre-mutation sweep, Stop parse, CLI) is narrated back to the developer as a `▸ paqad` line via the host's user-message channel; allow-path advisories use `systemMessage` instead of invisible stdout.
|
|
13
|
+
- Guardrails: a packaging-truth test suite pins that every runnable path/verb named in user-facing remediation surfaces resolves in the published package, and `src/stage-evidence/**` now holds a 100% coverage floor (statements, branches, functions, lines).
|
|
14
|
+
- Completion-backstop over-block fixed (decision `D-01KWYDTDZ24CV802R2HGDS4RH4`), removing two false blocks that hit every onboarded repo's first code change: (1) an implementation-drift canonical doc that does not exist on disk is no longer treated as an unresolved obligation — a code change cannot stale a framework-assumed doc (`docs/maintainers/architecture-map.md`, `docs/modules/README.md`) the project never created; existing drift docs are still flagged and required per-module docs stay enforced; (2) test-evidence strength is a provider-workflow concern the agent-independent backstop cannot collect, so at backstop origins it now escalates (visibly) instead of hard-blocking — in-session and CI still enforce it.
|
|
15
|
+
|
|
16
|
+
## 1.45.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- b07dc02: Decision Pause now mints packets on more of the forks that matter (#300, option B2):
|
|
21
|
+
|
|
22
|
+
- **Self-arm broadened to architecture-path.** Alongside create-vs-reuse (0.92), the opt-in self-arm minter now also arms on a new tight `explicit-path-fork` detector signal (0.90) — two distinct file paths offered as alternatives ("live in X or Y", "X vs Y"). The pre-existing broad architecture-path signals (a bare "or", two paths merely mentioned) stay at 0.64 and never clear the arming bar, so a stray "or" cannot mint a pause. Self-arm remains OFF by default.
|
|
23
|
+
- **spec.change now has a deterministic minter.** A new always-on, no-opt-in spec-change guard runs at the pre-mutation seam: when a persisted frozen spec's source markdown has moved since freeze (`isFrozenSpecStale`), it mints one `spec.change` pause via `buildSpecChangePacket`. It is naturally inert until a spec is frozen and its sidecar persisted (`writeFrozenSpec`), so nothing changes for projects that do not use the spec-freeze lifecycle. Both minters only write a pending packet; the existing decision-pause gate still owns the block on the next edit.
|
|
24
|
+
|
|
25
|
+
Cross-provider: the architecture-path leg inherits self-arm's existing transcript-based provider coverage (parity with `HOOK_COVERAGE_MATRIX`); the spec-change guard is provider-independent (it reads spec files on disk, not the turn transcript).
|
|
26
|
+
|
|
27
|
+
Also fixes `buildSpecChangePacket` copy that could never pass `lintDecisionCopy` (banned word "invariant", non-approved label verb, em dashes), which had silently blocked the packet from ever being written to the pending store.
|
|
28
|
+
|
|
29
|
+
## 1.44.1
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- 91e4798: Fix the Claude Stop hook so it respects the paqad enable/disable flag and can no longer wedge a session in an infinite loop.
|
|
34
|
+
|
|
35
|
+
- **Respects ON/OFF from the real project root.** `verification-completion.mjs` now resolves the project root via `CLAUDE_PROJECT_DIR` / `PAQAD_PROJECT_ROOT` (cwd fallback) like the sibling Stop hooks, instead of raw `process.cwd()`. A project set to `paqad_enable=false` is honored even when the host launched the hook from a subdirectory (previously the disable flag was missed and the OFF project was still blocked).
|
|
36
|
+
- **Bites once, never loops.** Every blocking Stop hook now reads Claude's `stop_hook_active`: the gate still blocks (exit 2) on the first stop so the model gets a turn to fix it, but once it is already inside a Stop-hook continuation it steps aside (surfaces the summary, exits 0). An unresolvable verdict can no longer drive an infinite Stop loop. The git/CI backstop remains the hard, non-bypassable layer.
|
|
37
|
+
|
|
3
38
|
## 1.44.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/dist/cli/index.js
CHANGED
|
@@ -9772,7 +9772,7 @@ import { pathToFileURL } from "url";
|
|
|
9772
9772
|
|
|
9773
9773
|
// src/cli/program.ts
|
|
9774
9774
|
init_esm_shims();
|
|
9775
|
-
import { Command as
|
|
9775
|
+
import { Command as Command24 } from "commander";
|
|
9776
9776
|
|
|
9777
9777
|
// src/index.ts
|
|
9778
9778
|
init_esm_shims();
|
|
@@ -16072,8 +16072,8 @@ function isPlaceholder(tokens) {
|
|
|
16072
16072
|
return tokens.$comment === DESIGN_TOKENS_PLACEHOLDER_NOTE;
|
|
16073
16073
|
}
|
|
16074
16074
|
var DesignTokenService = class {
|
|
16075
|
-
constructor(
|
|
16076
|
-
this.validator =
|
|
16075
|
+
constructor(validator4 = new SchemaValidator()) {
|
|
16076
|
+
this.validator = validator4;
|
|
16077
16077
|
}
|
|
16078
16078
|
async seed(projectRoot) {
|
|
16079
16079
|
const target = join53(projectRoot, PATHS.DESIGN_TOKENS_FILE);
|
|
@@ -18302,7 +18302,7 @@ var HealthChecker = class {
|
|
|
18302
18302
|
}
|
|
18303
18303
|
checkFrameworkArtifacts(projectRoot) {
|
|
18304
18304
|
const required = [PATHS.PROJECT_PROFILE, PATHS.FRAMEWORK_PATH];
|
|
18305
|
-
const missing = required.filter((
|
|
18305
|
+
const missing = required.filter((relative25) => !existsSync32(join58(projectRoot, relative25)));
|
|
18306
18306
|
return missing.length === 0 ? pass("Framework artifacts exist", "Framework artifacts are present") : fail(
|
|
18307
18307
|
"Framework artifacts exist",
|
|
18308
18308
|
`Missing framework artifacts: ${missing.join(", ")}`,
|
|
@@ -22714,8 +22714,8 @@ function loadDeliveryPolicy(projectRoot) {
|
|
|
22714
22714
|
]
|
|
22715
22715
|
};
|
|
22716
22716
|
}
|
|
22717
|
-
const
|
|
22718
|
-
const validation =
|
|
22717
|
+
const validator4 = new SchemaValidator();
|
|
22718
|
+
const validation = validator4.validate("delivery-policy", parsed);
|
|
22719
22719
|
if (!validation.valid) {
|
|
22720
22720
|
return {
|
|
22721
22721
|
policy: withDetection(projectRoot, defaults),
|
|
@@ -23700,8 +23700,8 @@ var OnboardingOrchestrator = class {
|
|
|
23700
23700
|
options.projectRoot
|
|
23701
23701
|
);
|
|
23702
23702
|
profile.intelligence = applyRagSelection(profile.intelligence, void 0);
|
|
23703
|
-
const
|
|
23704
|
-
const validation =
|
|
23703
|
+
const validator4 = new SchemaValidator();
|
|
23704
|
+
const validation = validator4.validate("project-profile", profile);
|
|
23705
23705
|
const modules = await discoverModules(options.projectRoot);
|
|
23706
23706
|
if (!validation.valid) {
|
|
23707
23707
|
throw new Error(validation.errors.map((error) => error.message).join("; "));
|
|
@@ -23937,8 +23937,8 @@ var OnboardingOrchestrator = class {
|
|
|
23937
23937
|
options.projectRoot
|
|
23938
23938
|
);
|
|
23939
23939
|
profile.intelligence = applyRagSelection(profile.intelligence, void 0);
|
|
23940
|
-
const
|
|
23941
|
-
const validation =
|
|
23940
|
+
const validator4 = new SchemaValidator();
|
|
23941
|
+
const validation = validator4.validate("project-profile", profile);
|
|
23942
23942
|
if (!validation.valid) {
|
|
23943
23943
|
throw new ValidationError(validation.errors.map((error) => error.message).join("; "), {
|
|
23944
23944
|
projectRoot: options.projectRoot
|
|
@@ -25904,9 +25904,68 @@ import Ajv5 from "ajv";
|
|
|
25904
25904
|
// src/stage-evidence/types.ts
|
|
25905
25905
|
init_esm_shims();
|
|
25906
25906
|
var STAGE_EVIDENCE_DOC_TYPE = "paqad.stage-evidence";
|
|
25907
|
+
var STAGE_EVIDENCE_SCHEMA_VERSION = 1;
|
|
25907
25908
|
|
|
25908
25909
|
// src/stage-evidence/schema.ts
|
|
25910
|
+
var nullableString3 = { type: ["string", "null"] };
|
|
25911
|
+
var STAGE_EVIDENCE_SCHEMA = {
|
|
25912
|
+
$id: "paqad://schemas/stage-evidence.json",
|
|
25913
|
+
type: "object",
|
|
25914
|
+
additionalProperties: false,
|
|
25915
|
+
required: [
|
|
25916
|
+
"schema_version",
|
|
25917
|
+
"doc_type",
|
|
25918
|
+
"kind",
|
|
25919
|
+
"session_id",
|
|
25920
|
+
"conversation_ordinal",
|
|
25921
|
+
"ts",
|
|
25922
|
+
"adapter",
|
|
25923
|
+
"content_hash"
|
|
25924
|
+
],
|
|
25925
|
+
properties: {
|
|
25926
|
+
schema_version: { type: "integer", const: 1 },
|
|
25927
|
+
doc_type: { const: STAGE_EVIDENCE_DOC_TYPE },
|
|
25928
|
+
kind: { enum: ["open", "stage_start", "stage_end", "verify", "close"] },
|
|
25929
|
+
session_id: { type: "string", minLength: 1 },
|
|
25930
|
+
conversation_ordinal: { type: "integer", minimum: 1 },
|
|
25931
|
+
ts: { type: "string", minLength: 1 },
|
|
25932
|
+
adapter: { type: "string", minLength: 1 },
|
|
25933
|
+
stage: nullableString3,
|
|
25934
|
+
event_status: {
|
|
25935
|
+
type: ["string", "null"],
|
|
25936
|
+
enum: ["started", "completed", "skipped", "failed", "redone", "inferred", null]
|
|
25937
|
+
},
|
|
25938
|
+
evidence_source: {
|
|
25939
|
+
type: ["string", "null"],
|
|
25940
|
+
enum: ["live-mark", "inferred-artifact", "inferred-git", "redo", null]
|
|
25941
|
+
},
|
|
25942
|
+
artifact_paths: { type: ["array", "null"], items: { type: "string" } },
|
|
25943
|
+
artifact_digest: nullableString3,
|
|
25944
|
+
subject_digest: nullableString3,
|
|
25945
|
+
lane: { type: ["string", "null"], enum: ["fast", "graduated", "full", null] },
|
|
25946
|
+
note: nullableString3,
|
|
25947
|
+
content_hash: { type: "string", minLength: 1 }
|
|
25948
|
+
}
|
|
25949
|
+
};
|
|
25909
25950
|
var ajv4 = new Ajv5({ allErrors: true, allowUnionTypes: true });
|
|
25951
|
+
var compiled3;
|
|
25952
|
+
function validator3() {
|
|
25953
|
+
if (!compiled3) {
|
|
25954
|
+
compiled3 = ajv4.compile(STAGE_EVIDENCE_SCHEMA);
|
|
25955
|
+
}
|
|
25956
|
+
return compiled3;
|
|
25957
|
+
}
|
|
25958
|
+
function formatValidationError(error) {
|
|
25959
|
+
return `${error.instancePath || "(root)"} ${error.message ?? "invalid"}`;
|
|
25960
|
+
}
|
|
25961
|
+
function validateStageEvidenceRow(row) {
|
|
25962
|
+
const validate = validator3();
|
|
25963
|
+
if (validate(row)) {
|
|
25964
|
+
return [];
|
|
25965
|
+
}
|
|
25966
|
+
const errors = validate.errors;
|
|
25967
|
+
return errors.map(formatValidationError);
|
|
25968
|
+
}
|
|
25910
25969
|
|
|
25911
25970
|
// src/stage-evidence/recorder.ts
|
|
25912
25971
|
init_session();
|
|
@@ -25914,6 +25973,120 @@ init_session();
|
|
|
25914
25973
|
// src/stage-evidence/stages.ts
|
|
25915
25974
|
init_esm_shims();
|
|
25916
25975
|
var STAGE_EVIDENCE_STAGES = [...STAGE_ORDER];
|
|
25976
|
+
var COMPLETION_ANCHORED_STAGES = ["review"];
|
|
25977
|
+
function isKnownStage(stage) {
|
|
25978
|
+
return STAGE_EVIDENCE_STAGES.includes(stage);
|
|
25979
|
+
}
|
|
25980
|
+
function isCompletionAnchoredStage(stage) {
|
|
25981
|
+
return COMPLETION_ANCHORED_STAGES.includes(stage);
|
|
25982
|
+
}
|
|
25983
|
+
function stageIndex(stage) {
|
|
25984
|
+
return STAGE_EVIDENCE_STAGES.indexOf(stage);
|
|
25985
|
+
}
|
|
25986
|
+
|
|
25987
|
+
// src/stage-evidence/recorder.ts
|
|
25988
|
+
var APPEND_OPTS3 = (now) => ({
|
|
25989
|
+
schemaVersion: STAGE_EVIDENCE_SCHEMA_VERSION,
|
|
25990
|
+
validate: (row) => validateStageEvidenceRow(row),
|
|
25991
|
+
now
|
|
25992
|
+
});
|
|
25993
|
+
function changeKey(sessionId, ordinal) {
|
|
25994
|
+
return `${sessionId}#${ordinal}`;
|
|
25995
|
+
}
|
|
25996
|
+
function openStageEvidence(projectRoot, ctx) {
|
|
25997
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
25998
|
+
const { ordinal } = openSessionDoc(
|
|
25999
|
+
projectRoot,
|
|
26000
|
+
STAGE_EVIDENCE_DOC_TYPE,
|
|
26001
|
+
sessionId,
|
|
26002
|
+
{ adapter: ctx.adapter, lane: ctx.lane ?? null },
|
|
26003
|
+
APPEND_OPTS3(ctx.now)
|
|
26004
|
+
);
|
|
26005
|
+
return { sessionId, ordinal, changeKey: changeKey(sessionId, ordinal) };
|
|
26006
|
+
}
|
|
26007
|
+
function resolveOrdinal2(projectRoot, sessionId, ctx) {
|
|
26008
|
+
if (ctx.ordinal && ctx.ordinal > 0) {
|
|
26009
|
+
return ctx.ordinal;
|
|
26010
|
+
}
|
|
26011
|
+
const current = currentOrdinal(projectRoot, STAGE_EVIDENCE_DOC_TYPE, sessionId);
|
|
26012
|
+
if (current > 0) {
|
|
26013
|
+
return current;
|
|
26014
|
+
}
|
|
26015
|
+
return openStageEvidence(projectRoot, ctx).ordinal;
|
|
26016
|
+
}
|
|
26017
|
+
function highestStartedIndex(rows) {
|
|
26018
|
+
let highest = -1;
|
|
26019
|
+
for (const row of rows) {
|
|
26020
|
+
if (row.kind === "stage_start" && typeof row.stage === "string") {
|
|
26021
|
+
highest = Math.max(highest, stageIndex(row.stage));
|
|
26022
|
+
}
|
|
26023
|
+
}
|
|
26024
|
+
return highest;
|
|
26025
|
+
}
|
|
26026
|
+
function startStage(projectRoot, stage, ctx) {
|
|
26027
|
+
if (!isKnownStage(stage)) {
|
|
26028
|
+
throw new Error(`Unknown stage "${stage}" \u2014 not in the feature-development registry.`);
|
|
26029
|
+
}
|
|
26030
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
26031
|
+
const ordinal = resolveOrdinal2(projectRoot, sessionId, ctx);
|
|
26032
|
+
const rows = readSessionUnit(projectRoot, STAGE_EVIDENCE_DOC_TYPE, sessionId, ordinal);
|
|
26033
|
+
const highest = highestStartedIndex(rows);
|
|
26034
|
+
const index = stageIndex(stage);
|
|
26035
|
+
if (!isCompletionAnchoredStage(stage) && highest >= 0 && index < highest) {
|
|
26036
|
+
throw new Error(
|
|
26037
|
+
`Out-of-order stage "${stage}": a later stage already started. Stages must run in registry order.`
|
|
26038
|
+
);
|
|
26039
|
+
}
|
|
26040
|
+
return append(projectRoot, sessionId, ordinal, ctx, {
|
|
26041
|
+
kind: "stage_start",
|
|
26042
|
+
stage,
|
|
26043
|
+
event_status: "started",
|
|
26044
|
+
evidence_source: "live-mark"
|
|
26045
|
+
});
|
|
26046
|
+
}
|
|
26047
|
+
function endStage(projectRoot, stage, input3, ctx) {
|
|
26048
|
+
if (!isKnownStage(stage)) {
|
|
26049
|
+
throw new Error(`Unknown stage "${stage}" \u2014 not in the feature-development registry.`);
|
|
26050
|
+
}
|
|
26051
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
26052
|
+
const ordinal = resolveOrdinal2(projectRoot, sessionId, ctx);
|
|
26053
|
+
const artifactPaths = input3.artifactPaths ?? [];
|
|
26054
|
+
const artifactDigest = artifactPaths.length > 0 ? hashArtifacts(projectRoot, artifactPaths) : null;
|
|
26055
|
+
const subjectDigest = stage === "development" ? input3.subjectDigest ?? artifactDigest : input3.subjectDigest ?? null;
|
|
26056
|
+
return append(projectRoot, sessionId, ordinal, ctx, {
|
|
26057
|
+
kind: "stage_end",
|
|
26058
|
+
stage,
|
|
26059
|
+
event_status: "completed",
|
|
26060
|
+
evidence_source: "live-mark",
|
|
26061
|
+
artifact_paths: artifactPaths.length > 0 ? artifactPaths : null,
|
|
26062
|
+
artifact_digest: artifactDigest,
|
|
26063
|
+
subject_digest: subjectDigest,
|
|
26064
|
+
note: input3.note ?? null
|
|
26065
|
+
});
|
|
26066
|
+
}
|
|
26067
|
+
function hashArtifacts(projectRoot, artifactPaths) {
|
|
26068
|
+
const perFile = [...artifactPaths].sort().map((rel) => {
|
|
26069
|
+
const abs = join129(projectRoot, rel);
|
|
26070
|
+
let bytes;
|
|
26071
|
+
try {
|
|
26072
|
+
bytes = readFileSync56(abs);
|
|
26073
|
+
} catch {
|
|
26074
|
+
return `${rel}:absent`;
|
|
26075
|
+
}
|
|
26076
|
+
return `${rel}:${createHash29("sha256").update(bytes).digest("hex")}`;
|
|
26077
|
+
});
|
|
26078
|
+
return `sha256-${createHash29("sha256").update(perFile.join("\n")).digest("hex")}`;
|
|
26079
|
+
}
|
|
26080
|
+
function append(projectRoot, sessionId, ordinal, ctx, fields) {
|
|
26081
|
+
return appendSessionEvent(
|
|
26082
|
+
projectRoot,
|
|
26083
|
+
STAGE_EVIDENCE_DOC_TYPE,
|
|
26084
|
+
sessionId,
|
|
26085
|
+
ordinal,
|
|
26086
|
+
{ conversation_ordinal: ordinal, adapter: ctx.adapter, lane: ctx.lane ?? null, ...fields },
|
|
26087
|
+
APPEND_OPTS3(ctx.now)
|
|
26088
|
+
);
|
|
26089
|
+
}
|
|
25917
26090
|
|
|
25918
26091
|
// src/stage-evidence/finalize.ts
|
|
25919
26092
|
init_session();
|
|
@@ -26122,7 +26295,7 @@ init_cancelled_error();
|
|
|
26122
26295
|
init_events();
|
|
26123
26296
|
|
|
26124
26297
|
// src/index.ts
|
|
26125
|
-
var VERSION = "1.
|
|
26298
|
+
var VERSION = "1.46.0";
|
|
26126
26299
|
|
|
26127
26300
|
// src/cli/commands/audit.ts
|
|
26128
26301
|
init_esm_shims();
|
|
@@ -29116,12 +29289,12 @@ import { existsSync as existsSync78, readdirSync as readdirSync15 } from "fs";
|
|
|
29116
29289
|
import { join as join148 } from "path";
|
|
29117
29290
|
import YAML19 from "yaml";
|
|
29118
29291
|
var EDITABLE_EXTENSIONS = [".md", ".yml", ".yaml", ".json"];
|
|
29119
|
-
function buildNode(absolute,
|
|
29292
|
+
function buildNode(absolute, relative25, name) {
|
|
29120
29293
|
const entries = readdirSync15(absolute, { withFileTypes: true });
|
|
29121
29294
|
const children = [];
|
|
29122
29295
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
29123
29296
|
if (entry.name.startsWith(".")) continue;
|
|
29124
|
-
const childRelative =
|
|
29297
|
+
const childRelative = relative25 === "" ? entry.name : `${relative25}/${entry.name}`;
|
|
29125
29298
|
if (entry.isDirectory()) {
|
|
29126
29299
|
const child = buildNode(join148(absolute, entry.name), childRelative, entry.name);
|
|
29127
29300
|
if (child) children.push(child);
|
|
@@ -29129,7 +29302,7 @@ function buildNode(absolute, relative24, name) {
|
|
|
29129
29302
|
children.push({ path: childRelative, name: entry.name, type: "file" });
|
|
29130
29303
|
}
|
|
29131
29304
|
}
|
|
29132
|
-
return { path:
|
|
29305
|
+
return { path: relative25, name, type: "directory", children };
|
|
29133
29306
|
}
|
|
29134
29307
|
function listInstructionsTree(projectRoot) {
|
|
29135
29308
|
const root = join148(projectRoot, PATHS.INSTRUCTIONS_DIR);
|
|
@@ -29242,7 +29415,7 @@ function counted(count, singular, plural, zero) {
|
|
|
29242
29415
|
}
|
|
29243
29416
|
function buildInventory(projectRoot, options = {}) {
|
|
29244
29417
|
const paqadHome = options.paqadHome ?? join149(homedir10(), ".paqad-ai");
|
|
29245
|
-
const at = (
|
|
29418
|
+
const at = (relative25) => join149(projectRoot, relative25);
|
|
29246
29419
|
const profile = parseYamlFile(at(PATHS.PROJECT_PROFILE));
|
|
29247
29420
|
const activeCapabilities = Array.isArray(profile?.active_capabilities) ? profile.active_capabilities : [];
|
|
29248
29421
|
const intelligence = profile?.intelligence ?? null;
|
|
@@ -29764,7 +29937,7 @@ function dirHasEntries(path11) {
|
|
|
29764
29937
|
}
|
|
29765
29938
|
}
|
|
29766
29939
|
function buildOnboardingChecklist(projectRoot) {
|
|
29767
|
-
const at = (
|
|
29940
|
+
const at = (relative25) => join150(projectRoot, relative25);
|
|
29768
29941
|
const agentConnected = [PATHS.CLAUDE_MD, PATHS.AGENTS_MD, PATHS.ANTIGRAVITY_MD, PATHS.GEMINI_MD].some(
|
|
29769
29942
|
(entry) => existsSync80(at(entry))
|
|
29770
29943
|
) && existsSync80(at(PATHS.ONBOARDING_MANIFEST));
|
|
@@ -32514,14 +32687,14 @@ data: ${JSON.stringify(data)}
|
|
|
32514
32687
|
return;
|
|
32515
32688
|
}
|
|
32516
32689
|
if (instructionsFileMatch && req.method === "PUT") {
|
|
32517
|
-
const
|
|
32690
|
+
const relative25 = decodeURIComponent(instructionsFileMatch[1]);
|
|
32518
32691
|
await handleMutation(req, res, async () => {
|
|
32519
32692
|
const body = await readJsonBody2(req);
|
|
32520
32693
|
if (typeof body.content !== "string") {
|
|
32521
32694
|
throw new Error("Body must include the file `content` as a string.");
|
|
32522
32695
|
}
|
|
32523
32696
|
return writeManagedFile(options.projectRoot, {
|
|
32524
|
-
relativePath: `${PATHS.INSTRUCTIONS_DIR}/${
|
|
32697
|
+
relativePath: `${PATHS.INSTRUCTIONS_DIR}/${relative25}`,
|
|
32525
32698
|
content: body.content,
|
|
32526
32699
|
baseHash: typeof body.baseHash === "string" ? body.baseHash : null,
|
|
32527
32700
|
action: "dashboard.instructions.write"
|
|
@@ -35326,10 +35499,95 @@ function resolveChangedFiles(projectRoot, contextChangedFiles) {
|
|
|
35326
35499
|
}
|
|
35327
35500
|
}
|
|
35328
35501
|
|
|
35502
|
+
// src/cli/commands/stage.ts
|
|
35503
|
+
init_esm_shims();
|
|
35504
|
+
import { Command as Command21 } from "commander";
|
|
35505
|
+
init_session();
|
|
35506
|
+
|
|
35507
|
+
// src/stage-evidence/live-writer.ts
|
|
35508
|
+
init_esm_shims();
|
|
35509
|
+
init_ledger();
|
|
35510
|
+
init_session();
|
|
35511
|
+
import { isAbsolute as isAbsolute6, relative as relative24 } from "pathe";
|
|
35512
|
+
function recordMarkedStage(projectRoot, input3) {
|
|
35513
|
+
if (!isKnownStage(input3.stage)) return false;
|
|
35514
|
+
const ctx = {
|
|
35515
|
+
sessionId: input3.sessionId,
|
|
35516
|
+
adapter: input3.adapter ?? "claude-code",
|
|
35517
|
+
now: input3.now
|
|
35518
|
+
};
|
|
35519
|
+
try {
|
|
35520
|
+
if (input3.phase === "start") {
|
|
35521
|
+
startStage(projectRoot, input3.stage, ctx);
|
|
35522
|
+
} else {
|
|
35523
|
+
endStage(projectRoot, input3.stage, { artifactPaths: input3.artifactPaths ?? [] }, ctx);
|
|
35524
|
+
}
|
|
35525
|
+
return true;
|
|
35526
|
+
} catch {
|
|
35527
|
+
return false;
|
|
35528
|
+
}
|
|
35529
|
+
}
|
|
35530
|
+
|
|
35531
|
+
// src/stage-evidence/narration.ts
|
|
35532
|
+
init_esm_shims();
|
|
35533
|
+
init_ledger();
|
|
35534
|
+
init_session();
|
|
35535
|
+
var STAGE_NARRATION = {
|
|
35536
|
+
ticket_intake: "picking up the ticket and reading what it needs",
|
|
35537
|
+
planning: "planning this out, checking which module it touches",
|
|
35538
|
+
specification: "writing the spec before any code",
|
|
35539
|
+
development: "building it to the spec",
|
|
35540
|
+
review: "reviewing the change for regressions",
|
|
35541
|
+
checks: "running the gates: format, tests, build, rules",
|
|
35542
|
+
documentation_sync: "syncing the docs this change touched",
|
|
35543
|
+
delivery: "delivering per the branch and PR conventions"
|
|
35544
|
+
};
|
|
35545
|
+
function stageNarrationLine(stage) {
|
|
35546
|
+
const text = STAGE_NARRATION[stage];
|
|
35547
|
+
return text ? `\u25B8 paqad \xB7 ${text}` : "";
|
|
35548
|
+
}
|
|
35549
|
+
function markerNarrationLine(stage, phase) {
|
|
35550
|
+
if (!STAGE_NARRATION[stage]) return "";
|
|
35551
|
+
if (phase === "start") return stageNarrationLine(stage);
|
|
35552
|
+
return `\u25B8 paqad \xB7 ${stage.replace(/_/g, " ")} done \u2014 evidence recorded in the ledger`;
|
|
35553
|
+
}
|
|
35554
|
+
|
|
35555
|
+
// src/cli/commands/stage.ts
|
|
35556
|
+
function createStageCommand() {
|
|
35557
|
+
return new Command21("stage").description(
|
|
35558
|
+
"Mark a feature-development stage boundary in the stage-evidence ledger (clears the pre-code block for planning/specification)"
|
|
35559
|
+
).argument("<phase>", "'start' or 'end'").argument("<stage>", `one of: ${STAGE_ORDER.join(", ")}`).option("--project-root <path>", "Project root", process.cwd()).option(
|
|
35560
|
+
"--session <id>",
|
|
35561
|
+
"Session id to record under (defaults to SE_SESSION / CLAUDE_SESSION_ID, then the shared ledger-session cache)"
|
|
35562
|
+
).action((phase, stage, options) => {
|
|
35563
|
+
if (phase !== "start" && phase !== "end") {
|
|
35564
|
+
console.error(`unknown phase "${phase}" \u2014 use 'start' or 'end'`);
|
|
35565
|
+
process.exitCode = 1;
|
|
35566
|
+
return;
|
|
35567
|
+
}
|
|
35568
|
+
const root = options.projectRoot;
|
|
35569
|
+
const sessionId = resolveSessionId(
|
|
35570
|
+
root,
|
|
35571
|
+
options.session ?? process.env.SE_SESSION ?? process.env.CLAUDE_SESSION_ID ?? null
|
|
35572
|
+
);
|
|
35573
|
+
const recorded = recordMarkedStage(root, { sessionId, stage, phase });
|
|
35574
|
+
if (!recorded) {
|
|
35575
|
+
console.error(
|
|
35576
|
+
`could not record "${stage} ${phase}" \u2014 unknown stage or out-of-order boundary. Stages, in order: ${STAGE_ORDER.join(", ")}`
|
|
35577
|
+
);
|
|
35578
|
+
process.exitCode = 1;
|
|
35579
|
+
return;
|
|
35580
|
+
}
|
|
35581
|
+
const line = markerNarrationLine(stage, phase);
|
|
35582
|
+
if (line) console.log(line);
|
|
35583
|
+
console.log(JSON.stringify({ recorded: true, stage, phase }));
|
|
35584
|
+
});
|
|
35585
|
+
}
|
|
35586
|
+
|
|
35329
35587
|
// src/cli/commands/status.ts
|
|
35330
35588
|
init_esm_shims();
|
|
35331
35589
|
import { resolve as resolve14 } from "path";
|
|
35332
|
-
import { Command as
|
|
35590
|
+
import { Command as Command22 } from "commander";
|
|
35333
35591
|
init_reconciler();
|
|
35334
35592
|
function collectDriftSignals(projectRoot) {
|
|
35335
35593
|
const drift = readDriftReport(projectRoot);
|
|
@@ -35349,7 +35607,7 @@ function driftSignalsTrip(signals) {
|
|
|
35349
35607
|
return signals.mmFindings > 0 || signals.staleModules.length > 0 || signals.expiredDecisions.length > 0 || signals.mmDocMissing > 0 || signals.blocked !== null;
|
|
35350
35608
|
}
|
|
35351
35609
|
function createStatusCommand() {
|
|
35352
|
-
return new
|
|
35610
|
+
return new Command22("status").description("Print a one-shot dashboard report (Markdown or JSON)").option("--format <fmt>", "Output format: markdown | json", "markdown").option("--project-root <path>", "Project root", process.cwd()).option(
|
|
35353
35611
|
"--fail-on-drift",
|
|
35354
35612
|
"Exit non-zero when module-map drift, stale module-health, expired MD-XXXX decisions, or MM-DOC-MISSING findings are present",
|
|
35355
35613
|
false
|
|
@@ -35391,9 +35649,9 @@ function createStatusCommand() {
|
|
|
35391
35649
|
|
|
35392
35650
|
// src/cli/commands/update.ts
|
|
35393
35651
|
init_esm_shims();
|
|
35394
|
-
import { Command as
|
|
35652
|
+
import { Command as Command23 } from "commander";
|
|
35395
35653
|
function createUpdateCommand() {
|
|
35396
|
-
return new
|
|
35654
|
+
return new Command23("update").description("Update framework-managed artifacts").option("--project-root <path>", "Project root", process.cwd()).option("--silent", "Suppress output; write results to audit log only").action(async (options) => {
|
|
35397
35655
|
try {
|
|
35398
35656
|
const report = await new FrameworkUpdater().run(options.projectRoot);
|
|
35399
35657
|
if (!options.silent) {
|
|
@@ -35417,7 +35675,7 @@ function createUpdateCommand() {
|
|
|
35417
35675
|
|
|
35418
35676
|
// src/cli/program.ts
|
|
35419
35677
|
function createProgram() {
|
|
35420
|
-
const program = new
|
|
35678
|
+
const program = new Command24();
|
|
35421
35679
|
program.name("paqad-ai").description("AI Agency Framework for software agencies").version(VERSION).showSuggestionAfterError(true);
|
|
35422
35680
|
program.addCommand(createInstallCommand());
|
|
35423
35681
|
program.addCommand(createCapabilitiesCommand());
|
|
@@ -35440,6 +35698,7 @@ function createProgram() {
|
|
|
35440
35698
|
program.addCommand(createRagEvidenceCommand());
|
|
35441
35699
|
program.addCommand(createUpdateCommand());
|
|
35442
35700
|
program.addCommand(createPatternsCommand());
|
|
35701
|
+
program.addCommand(createStageCommand());
|
|
35443
35702
|
program.addCommand(createStatusCommand());
|
|
35444
35703
|
return program;
|
|
35445
35704
|
}
|