paqad-ai 1.44.1 → 1.46.1
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 +37 -0
- package/dist/cli/index.js +283 -32
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +120 -35
- package/dist/index.js.map +1 -1
- package/dist/kernel/gate.d.ts +5 -0
- package/dist/kernel/gate.js +646 -86
- package/dist/kernel/gate.js.map +1 -1
- package/dist/stage-evidence/live-writer.d.ts +10 -1
- package/dist/stage-evidence/live-writer.js +28 -32
- 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 +22 -32
- 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 +34 -3
- 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 +11 -3
- package/runtime/hooks/stage-marker-parse.mjs +12 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# paqad-ai
|
|
2
2
|
|
|
3
|
+
## 1.46.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c0e7efa: Fix #310: the feature-development stage gate blocked documentation-only work and could deadlock unclearably.
|
|
8
|
+
|
|
9
|
+
- **Scope.** The pre-mutation and completion stage gates now govern **feature development only**. A documentation-only change (`docs/**`, markdown) or a framework-internal change (`.paqad/**`) is no longer forced through the planning → specification → … → checks stages. The check is language-agnostic (an exclude list, not a `src/` allowlist), so it holds for any onboarded stack (Laravel `app/*.php`, Python, Go, …), and it keeps full teeth on real source edits.
|
|
10
|
+
- **No deadlock.** The live writer no longer stamps a stage (e.g. `development`/`documentation_sync`) before the pre-code stages are recorded — that phantom used to poison stage ordering so `planning` could never be recorded again. The recorder no longer rejects an out-of-order earlier `stage_start`; ordering is judged non-destructively by the completion fold, so the stages the gate demands can always be recorded and the same-turn marker remediation actually clears the block.
|
|
11
|
+
- **Consistent predicate.** An `end` with no matching `start` is now `inconclusive`, not silently `complete`, so the pre-mutation gate and the completion verifier agree a stage needs a start.
|
|
12
|
+
- **Reachable remedy.** Editing `.paqad/configs/.config.policy` (the `stages_mode` escape hatch) is no longer blocked by the gate it configures.
|
|
13
|
+
|
|
14
|
+
## 1.46.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- 944f52f: Stages gate: same-turn unblock that actually works, sentinel bootstrap un-deadlocked, and stage narration everywhere (#307).
|
|
19
|
+
|
|
20
|
+
- `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.
|
|
21
|
+
- 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.
|
|
22
|
+
- 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.
|
|
23
|
+
- 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.
|
|
24
|
+
- 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).
|
|
25
|
+
- 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.
|
|
26
|
+
|
|
27
|
+
## 1.45.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- b07dc02: Decision Pause now mints packets on more of the forks that matter (#300, option B2):
|
|
32
|
+
|
|
33
|
+
- **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.
|
|
34
|
+
- **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.
|
|
35
|
+
|
|
36
|
+
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).
|
|
37
|
+
|
|
38
|
+
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.
|
|
39
|
+
|
|
3
40
|
## 1.44.1
|
|
4
41
|
|
|
5
42
|
### Patch 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((relative26) => !existsSync32(join58(projectRoot, relative26)));
|
|
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,108 @@ init_session();
|
|
|
25914
25973
|
// src/stage-evidence/stages.ts
|
|
25915
25974
|
init_esm_shims();
|
|
25916
25975
|
var STAGE_EVIDENCE_STAGES = [...STAGE_ORDER];
|
|
25976
|
+
var MANDATORY_STAGES = [
|
|
25977
|
+
"planning",
|
|
25978
|
+
"specification",
|
|
25979
|
+
"development",
|
|
25980
|
+
"review",
|
|
25981
|
+
"checks",
|
|
25982
|
+
"documentation_sync"
|
|
25983
|
+
];
|
|
25984
|
+
var PRE_CODE_STAGES = MANDATORY_STAGES.slice(
|
|
25985
|
+
0,
|
|
25986
|
+
MANDATORY_STAGES.indexOf("development")
|
|
25987
|
+
);
|
|
25988
|
+
function isKnownStage(stage) {
|
|
25989
|
+
return STAGE_EVIDENCE_STAGES.includes(stage);
|
|
25990
|
+
}
|
|
25991
|
+
|
|
25992
|
+
// src/stage-evidence/recorder.ts
|
|
25993
|
+
var APPEND_OPTS3 = (now) => ({
|
|
25994
|
+
schemaVersion: STAGE_EVIDENCE_SCHEMA_VERSION,
|
|
25995
|
+
validate: (row) => validateStageEvidenceRow(row),
|
|
25996
|
+
now
|
|
25997
|
+
});
|
|
25998
|
+
function changeKey(sessionId, ordinal) {
|
|
25999
|
+
return `${sessionId}#${ordinal}`;
|
|
26000
|
+
}
|
|
26001
|
+
function openStageEvidence(projectRoot, ctx) {
|
|
26002
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
26003
|
+
const { ordinal } = openSessionDoc(
|
|
26004
|
+
projectRoot,
|
|
26005
|
+
STAGE_EVIDENCE_DOC_TYPE,
|
|
26006
|
+
sessionId,
|
|
26007
|
+
{ adapter: ctx.adapter, lane: ctx.lane ?? null },
|
|
26008
|
+
APPEND_OPTS3(ctx.now)
|
|
26009
|
+
);
|
|
26010
|
+
return { sessionId, ordinal, changeKey: changeKey(sessionId, ordinal) };
|
|
26011
|
+
}
|
|
26012
|
+
function resolveOrdinal2(projectRoot, sessionId, ctx) {
|
|
26013
|
+
if (ctx.ordinal && ctx.ordinal > 0) {
|
|
26014
|
+
return ctx.ordinal;
|
|
26015
|
+
}
|
|
26016
|
+
const current = currentOrdinal(projectRoot, STAGE_EVIDENCE_DOC_TYPE, sessionId);
|
|
26017
|
+
if (current > 0) {
|
|
26018
|
+
return current;
|
|
26019
|
+
}
|
|
26020
|
+
return openStageEvidence(projectRoot, ctx).ordinal;
|
|
26021
|
+
}
|
|
26022
|
+
function startStage(projectRoot, stage, ctx) {
|
|
26023
|
+
if (!isKnownStage(stage)) {
|
|
26024
|
+
throw new Error(`Unknown stage "${stage}" \u2014 not in the feature-development registry.`);
|
|
26025
|
+
}
|
|
26026
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
26027
|
+
const ordinal = resolveOrdinal2(projectRoot, sessionId, ctx);
|
|
26028
|
+
return append(projectRoot, sessionId, ordinal, ctx, {
|
|
26029
|
+
kind: "stage_start",
|
|
26030
|
+
stage,
|
|
26031
|
+
event_status: "started",
|
|
26032
|
+
evidence_source: "live-mark"
|
|
26033
|
+
});
|
|
26034
|
+
}
|
|
26035
|
+
function endStage(projectRoot, stage, input3, ctx) {
|
|
26036
|
+
if (!isKnownStage(stage)) {
|
|
26037
|
+
throw new Error(`Unknown stage "${stage}" \u2014 not in the feature-development registry.`);
|
|
26038
|
+
}
|
|
26039
|
+
const sessionId = resolveSessionId(projectRoot, ctx.sessionId);
|
|
26040
|
+
const ordinal = resolveOrdinal2(projectRoot, sessionId, ctx);
|
|
26041
|
+
const artifactPaths = input3.artifactPaths ?? [];
|
|
26042
|
+
const artifactDigest = artifactPaths.length > 0 ? hashArtifacts(projectRoot, artifactPaths) : null;
|
|
26043
|
+
const subjectDigest = stage === "development" ? input3.subjectDigest ?? artifactDigest : input3.subjectDigest ?? null;
|
|
26044
|
+
return append(projectRoot, sessionId, ordinal, ctx, {
|
|
26045
|
+
kind: "stage_end",
|
|
26046
|
+
stage,
|
|
26047
|
+
event_status: "completed",
|
|
26048
|
+
evidence_source: "live-mark",
|
|
26049
|
+
artifact_paths: artifactPaths.length > 0 ? artifactPaths : null,
|
|
26050
|
+
artifact_digest: artifactDigest,
|
|
26051
|
+
subject_digest: subjectDigest,
|
|
26052
|
+
note: input3.note ?? null
|
|
26053
|
+
});
|
|
26054
|
+
}
|
|
26055
|
+
function hashArtifacts(projectRoot, artifactPaths) {
|
|
26056
|
+
const perFile = [...artifactPaths].sort().map((rel) => {
|
|
26057
|
+
const abs = join129(projectRoot, rel);
|
|
26058
|
+
let bytes;
|
|
26059
|
+
try {
|
|
26060
|
+
bytes = readFileSync56(abs);
|
|
26061
|
+
} catch {
|
|
26062
|
+
return `${rel}:absent`;
|
|
26063
|
+
}
|
|
26064
|
+
return `${rel}:${createHash29("sha256").update(bytes).digest("hex")}`;
|
|
26065
|
+
});
|
|
26066
|
+
return `sha256-${createHash29("sha256").update(perFile.join("\n")).digest("hex")}`;
|
|
26067
|
+
}
|
|
26068
|
+
function append(projectRoot, sessionId, ordinal, ctx, fields) {
|
|
26069
|
+
return appendSessionEvent(
|
|
26070
|
+
projectRoot,
|
|
26071
|
+
STAGE_EVIDENCE_DOC_TYPE,
|
|
26072
|
+
sessionId,
|
|
26073
|
+
ordinal,
|
|
26074
|
+
{ conversation_ordinal: ordinal, adapter: ctx.adapter, lane: ctx.lane ?? null, ...fields },
|
|
26075
|
+
APPEND_OPTS3(ctx.now)
|
|
26076
|
+
);
|
|
26077
|
+
}
|
|
25917
26078
|
|
|
25918
26079
|
// src/stage-evidence/finalize.ts
|
|
25919
26080
|
init_session();
|
|
@@ -25933,6 +26094,10 @@ init_session();
|
|
|
25933
26094
|
init_esm_shims();
|
|
25934
26095
|
init_framework_config();
|
|
25935
26096
|
|
|
26097
|
+
// src/stage-evidence/scope.ts
|
|
26098
|
+
init_esm_shims();
|
|
26099
|
+
import { isAbsolute as isAbsolute3, relative as relative22 } from "pathe";
|
|
26100
|
+
|
|
25936
26101
|
// src/verification/repository/verdict.ts
|
|
25937
26102
|
init_esm_shims();
|
|
25938
26103
|
|
|
@@ -26080,7 +26245,7 @@ init_esm_shims();
|
|
|
26080
26245
|
init_esm_shims();
|
|
26081
26246
|
init_logger_registry();
|
|
26082
26247
|
import { mkdir as mkdir45, writeFile as writeFile45 } from "fs/promises";
|
|
26083
|
-
import { join as join134, relative as
|
|
26248
|
+
import { join as join134, relative as relative23 } from "path";
|
|
26084
26249
|
init_paths();
|
|
26085
26250
|
init_path_utils();
|
|
26086
26251
|
|
|
@@ -26122,7 +26287,7 @@ init_cancelled_error();
|
|
|
26122
26287
|
init_events();
|
|
26123
26288
|
|
|
26124
26289
|
// src/index.ts
|
|
26125
|
-
var VERSION = "1.
|
|
26290
|
+
var VERSION = "1.46.1";
|
|
26126
26291
|
|
|
26127
26292
|
// src/cli/commands/audit.ts
|
|
26128
26293
|
init_esm_shims();
|
|
@@ -27121,7 +27286,7 @@ function resolveRelativeSpec(projectRoot, spec) {
|
|
|
27121
27286
|
init_esm_shims();
|
|
27122
27287
|
init_paths();
|
|
27123
27288
|
import { existsSync as existsSync98 } from "fs";
|
|
27124
|
-
import { dirname as dirname69, isAbsolute as
|
|
27289
|
+
import { dirname as dirname69, isAbsolute as isAbsolute4, join as join169, resolve as resolve10 } from "path";
|
|
27125
27290
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
27126
27291
|
import { Command as Command4 } from "commander";
|
|
27127
27292
|
|
|
@@ -27219,7 +27384,7 @@ function buildNodeDetail(graph, nodeId, options) {
|
|
|
27219
27384
|
init_esm_shims();
|
|
27220
27385
|
import { existsSync as existsSync70 } from "fs";
|
|
27221
27386
|
import { readFile as readFile69, readdir as readdir15, stat as stat8 } from "fs/promises";
|
|
27222
|
-
import { extname as extname8, join as join138, relative as
|
|
27387
|
+
import { extname as extname8, join as join138, relative as relative24, sep as sep6 } from "path";
|
|
27223
27388
|
init_paths();
|
|
27224
27389
|
var KNOWN_TIERS = /* @__PURE__ */ new Set(["green", "amber", "red", "unknown"]);
|
|
27225
27390
|
function normaliseTier(value) {
|
|
@@ -27257,7 +27422,7 @@ function languageFromExtension(filePath) {
|
|
|
27257
27422
|
return map[ext] ?? null;
|
|
27258
27423
|
}
|
|
27259
27424
|
function toProjectRelative2(projectRoot, absolutePath) {
|
|
27260
|
-
const rel =
|
|
27425
|
+
const rel = relative24(projectRoot, absolutePath);
|
|
27261
27426
|
return rel === "" ? "." : rel.split(sep6).join("/");
|
|
27262
27427
|
}
|
|
27263
27428
|
function moduleNameForFile(relativePath, knownModules) {
|
|
@@ -29116,12 +29281,12 @@ import { existsSync as existsSync78, readdirSync as readdirSync15 } from "fs";
|
|
|
29116
29281
|
import { join as join148 } from "path";
|
|
29117
29282
|
import YAML19 from "yaml";
|
|
29118
29283
|
var EDITABLE_EXTENSIONS = [".md", ".yml", ".yaml", ".json"];
|
|
29119
|
-
function buildNode(absolute,
|
|
29284
|
+
function buildNode(absolute, relative26, name) {
|
|
29120
29285
|
const entries = readdirSync15(absolute, { withFileTypes: true });
|
|
29121
29286
|
const children = [];
|
|
29122
29287
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
29123
29288
|
if (entry.name.startsWith(".")) continue;
|
|
29124
|
-
const childRelative =
|
|
29289
|
+
const childRelative = relative26 === "" ? entry.name : `${relative26}/${entry.name}`;
|
|
29125
29290
|
if (entry.isDirectory()) {
|
|
29126
29291
|
const child = buildNode(join148(absolute, entry.name), childRelative, entry.name);
|
|
29127
29292
|
if (child) children.push(child);
|
|
@@ -29129,7 +29294,7 @@ function buildNode(absolute, relative24, name) {
|
|
|
29129
29294
|
children.push({ path: childRelative, name: entry.name, type: "file" });
|
|
29130
29295
|
}
|
|
29131
29296
|
}
|
|
29132
|
-
return { path:
|
|
29297
|
+
return { path: relative26, name, type: "directory", children };
|
|
29133
29298
|
}
|
|
29134
29299
|
function listInstructionsTree(projectRoot) {
|
|
29135
29300
|
const root = join148(projectRoot, PATHS.INSTRUCTIONS_DIR);
|
|
@@ -29242,7 +29407,7 @@ function counted(count, singular, plural, zero) {
|
|
|
29242
29407
|
}
|
|
29243
29408
|
function buildInventory(projectRoot, options = {}) {
|
|
29244
29409
|
const paqadHome = options.paqadHome ?? join149(homedir10(), ".paqad-ai");
|
|
29245
|
-
const at = (
|
|
29410
|
+
const at = (relative26) => join149(projectRoot, relative26);
|
|
29246
29411
|
const profile = parseYamlFile(at(PATHS.PROJECT_PROFILE));
|
|
29247
29412
|
const activeCapabilities = Array.isArray(profile?.active_capabilities) ? profile.active_capabilities : [];
|
|
29248
29413
|
const intelligence = profile?.intelligence ?? null;
|
|
@@ -29764,7 +29929,7 @@ function dirHasEntries(path11) {
|
|
|
29764
29929
|
}
|
|
29765
29930
|
}
|
|
29766
29931
|
function buildOnboardingChecklist(projectRoot) {
|
|
29767
|
-
const at = (
|
|
29932
|
+
const at = (relative26) => join150(projectRoot, relative26);
|
|
29768
29933
|
const agentConnected = [PATHS.CLAUDE_MD, PATHS.AGENTS_MD, PATHS.ANTIGRAVITY_MD, PATHS.GEMINI_MD].some(
|
|
29769
29934
|
(entry) => existsSync80(at(entry))
|
|
29770
29935
|
) && existsSync80(at(PATHS.ONBOARDING_MANIFEST));
|
|
@@ -32514,14 +32679,14 @@ data: ${JSON.stringify(data)}
|
|
|
32514
32679
|
return;
|
|
32515
32680
|
}
|
|
32516
32681
|
if (instructionsFileMatch && req.method === "PUT") {
|
|
32517
|
-
const
|
|
32682
|
+
const relative26 = decodeURIComponent(instructionsFileMatch[1]);
|
|
32518
32683
|
await handleMutation(req, res, async () => {
|
|
32519
32684
|
const body = await readJsonBody2(req);
|
|
32520
32685
|
if (typeof body.content !== "string") {
|
|
32521
32686
|
throw new Error("Body must include the file `content` as a string.");
|
|
32522
32687
|
}
|
|
32523
32688
|
return writeManagedFile(options.projectRoot, {
|
|
32524
|
-
relativePath: `${PATHS.INSTRUCTIONS_DIR}/${
|
|
32689
|
+
relativePath: `${PATHS.INSTRUCTIONS_DIR}/${relative26}`,
|
|
32525
32690
|
content: body.content,
|
|
32526
32691
|
baseHash: typeof body.baseHash === "string" ? body.baseHash : null,
|
|
32527
32692
|
action: "dashboard.instructions.write"
|
|
@@ -32837,7 +33002,7 @@ function openBrowser(options) {
|
|
|
32837
33002
|
var DEFAULT_PORT = 5372;
|
|
32838
33003
|
function resolveStaticDir(override) {
|
|
32839
33004
|
if (override) {
|
|
32840
|
-
return
|
|
33005
|
+
return isAbsolute4(override) ? override : resolve10(process.cwd(), override);
|
|
32841
33006
|
}
|
|
32842
33007
|
const here = dirname69(fileURLToPath3(import.meta.url));
|
|
32843
33008
|
const candidates = [
|
|
@@ -33037,14 +33202,14 @@ function createEvidenceCommand() {
|
|
|
33037
33202
|
init_esm_shims();
|
|
33038
33203
|
init_paths();
|
|
33039
33204
|
import { existsSync as existsSync99 } from "fs";
|
|
33040
|
-
import { dirname as dirname71, isAbsolute as
|
|
33205
|
+
import { dirname as dirname71, isAbsolute as isAbsolute5, join as join170, resolve as resolve12 } from "path";
|
|
33041
33206
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
33042
33207
|
import { Command as Command9 } from "commander";
|
|
33043
33208
|
var DEFAULT_PORT2 = 5372;
|
|
33044
33209
|
var DEPRECATION_LINE = "paqad-ai graph has moved into the dashboard. Opening the dashboard on the Graph view. Run paqad-ai dashboard next time.";
|
|
33045
33210
|
function resolveStaticDir2(override) {
|
|
33046
33211
|
if (override) {
|
|
33047
|
-
return
|
|
33212
|
+
return isAbsolute5(override) ? override : resolve12(process.cwd(), override);
|
|
33048
33213
|
}
|
|
33049
33214
|
const here = dirname71(fileURLToPath4(import.meta.url));
|
|
33050
33215
|
const candidates = [
|
|
@@ -33888,7 +34053,7 @@ function createPacksCommand() {
|
|
|
33888
34053
|
init_esm_shims();
|
|
33889
34054
|
init_project_intelligence();
|
|
33890
34055
|
import { readFileSync as readFileSync76 } from "fs";
|
|
33891
|
-
import { isAbsolute as
|
|
34056
|
+
import { isAbsolute as isAbsolute6, join as join174 } from "path";
|
|
33892
34057
|
import { confirm, input as input2, select as select3 } from "@inquirer/prompts";
|
|
33893
34058
|
import { Command as Command18 } from "commander";
|
|
33894
34059
|
init_framework_config();
|
|
@@ -34875,7 +35040,7 @@ function createRagCommand() {
|
|
|
34875
35040
|
readFile: (path11) => {
|
|
34876
35041
|
try {
|
|
34877
35042
|
return readFileSync76(
|
|
34878
|
-
|
|
35043
|
+
isAbsolute6(path11) ? path11 : join174(options.projectRoot, path11),
|
|
34879
35044
|
"utf8"
|
|
34880
35045
|
);
|
|
34881
35046
|
} catch {
|
|
@@ -35326,10 +35491,95 @@ function resolveChangedFiles(projectRoot, contextChangedFiles) {
|
|
|
35326
35491
|
}
|
|
35327
35492
|
}
|
|
35328
35493
|
|
|
35494
|
+
// src/cli/commands/stage.ts
|
|
35495
|
+
init_esm_shims();
|
|
35496
|
+
import { Command as Command21 } from "commander";
|
|
35497
|
+
init_session();
|
|
35498
|
+
|
|
35499
|
+
// src/stage-evidence/live-writer.ts
|
|
35500
|
+
init_esm_shims();
|
|
35501
|
+
init_ledger();
|
|
35502
|
+
init_session();
|
|
35503
|
+
import { isAbsolute as isAbsolute7, relative as relative25 } from "pathe";
|
|
35504
|
+
function recordMarkedStage(projectRoot, input3) {
|
|
35505
|
+
if (!isKnownStage(input3.stage)) return false;
|
|
35506
|
+
const ctx = {
|
|
35507
|
+
sessionId: input3.sessionId,
|
|
35508
|
+
adapter: input3.adapter ?? "claude-code",
|
|
35509
|
+
now: input3.now
|
|
35510
|
+
};
|
|
35511
|
+
try {
|
|
35512
|
+
if (input3.phase === "start") {
|
|
35513
|
+
startStage(projectRoot, input3.stage, ctx);
|
|
35514
|
+
} else {
|
|
35515
|
+
endStage(projectRoot, input3.stage, { artifactPaths: input3.artifactPaths ?? [] }, ctx);
|
|
35516
|
+
}
|
|
35517
|
+
return true;
|
|
35518
|
+
} catch {
|
|
35519
|
+
return false;
|
|
35520
|
+
}
|
|
35521
|
+
}
|
|
35522
|
+
|
|
35523
|
+
// src/stage-evidence/narration.ts
|
|
35524
|
+
init_esm_shims();
|
|
35525
|
+
init_ledger();
|
|
35526
|
+
init_session();
|
|
35527
|
+
var STAGE_NARRATION = {
|
|
35528
|
+
ticket_intake: "picking up the ticket and reading what it needs",
|
|
35529
|
+
planning: "planning this out, checking which module it touches",
|
|
35530
|
+
specification: "writing the spec before any code",
|
|
35531
|
+
development: "building it to the spec",
|
|
35532
|
+
review: "reviewing the change for regressions",
|
|
35533
|
+
checks: "running the gates: format, tests, build, rules",
|
|
35534
|
+
documentation_sync: "syncing the docs this change touched",
|
|
35535
|
+
delivery: "delivering per the branch and PR conventions"
|
|
35536
|
+
};
|
|
35537
|
+
function stageNarrationLine(stage) {
|
|
35538
|
+
const text = STAGE_NARRATION[stage];
|
|
35539
|
+
return text ? `\u25B8 paqad \xB7 ${text}` : "";
|
|
35540
|
+
}
|
|
35541
|
+
function markerNarrationLine(stage, phase) {
|
|
35542
|
+
if (!STAGE_NARRATION[stage]) return "";
|
|
35543
|
+
if (phase === "start") return stageNarrationLine(stage);
|
|
35544
|
+
return `\u25B8 paqad \xB7 ${stage.replace(/_/g, " ")} done \u2014 evidence recorded in the ledger`;
|
|
35545
|
+
}
|
|
35546
|
+
|
|
35547
|
+
// src/cli/commands/stage.ts
|
|
35548
|
+
function createStageCommand() {
|
|
35549
|
+
return new Command21("stage").description(
|
|
35550
|
+
"Mark a feature-development stage boundary in the stage-evidence ledger (clears the pre-code block for planning/specification)"
|
|
35551
|
+
).argument("<phase>", "'start' or 'end'").argument("<stage>", `one of: ${STAGE_ORDER.join(", ")}`).option("--project-root <path>", "Project root", process.cwd()).option(
|
|
35552
|
+
"--session <id>",
|
|
35553
|
+
"Session id to record under (defaults to SE_SESSION / CLAUDE_SESSION_ID, then the shared ledger-session cache)"
|
|
35554
|
+
).action((phase, stage, options) => {
|
|
35555
|
+
if (phase !== "start" && phase !== "end") {
|
|
35556
|
+
console.error(`unknown phase "${phase}" \u2014 use 'start' or 'end'`);
|
|
35557
|
+
process.exitCode = 1;
|
|
35558
|
+
return;
|
|
35559
|
+
}
|
|
35560
|
+
const root = options.projectRoot;
|
|
35561
|
+
const sessionId = resolveSessionId(
|
|
35562
|
+
root,
|
|
35563
|
+
options.session ?? process.env.SE_SESSION ?? process.env.CLAUDE_SESSION_ID ?? null
|
|
35564
|
+
);
|
|
35565
|
+
const recorded = recordMarkedStage(root, { sessionId, stage, phase });
|
|
35566
|
+
if (!recorded) {
|
|
35567
|
+
console.error(
|
|
35568
|
+
`could not record "${stage} ${phase}" \u2014 unknown stage "${stage}". Stages, in order: ${STAGE_ORDER.join(", ")}`
|
|
35569
|
+
);
|
|
35570
|
+
process.exitCode = 1;
|
|
35571
|
+
return;
|
|
35572
|
+
}
|
|
35573
|
+
const line = markerNarrationLine(stage, phase);
|
|
35574
|
+
if (line) console.log(line);
|
|
35575
|
+
console.log(JSON.stringify({ recorded: true, stage, phase }));
|
|
35576
|
+
});
|
|
35577
|
+
}
|
|
35578
|
+
|
|
35329
35579
|
// src/cli/commands/status.ts
|
|
35330
35580
|
init_esm_shims();
|
|
35331
35581
|
import { resolve as resolve14 } from "path";
|
|
35332
|
-
import { Command as
|
|
35582
|
+
import { Command as Command22 } from "commander";
|
|
35333
35583
|
init_reconciler();
|
|
35334
35584
|
function collectDriftSignals(projectRoot) {
|
|
35335
35585
|
const drift = readDriftReport(projectRoot);
|
|
@@ -35349,7 +35599,7 @@ function driftSignalsTrip(signals) {
|
|
|
35349
35599
|
return signals.mmFindings > 0 || signals.staleModules.length > 0 || signals.expiredDecisions.length > 0 || signals.mmDocMissing > 0 || signals.blocked !== null;
|
|
35350
35600
|
}
|
|
35351
35601
|
function createStatusCommand() {
|
|
35352
|
-
return new
|
|
35602
|
+
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
35603
|
"--fail-on-drift",
|
|
35354
35604
|
"Exit non-zero when module-map drift, stale module-health, expired MD-XXXX decisions, or MM-DOC-MISSING findings are present",
|
|
35355
35605
|
false
|
|
@@ -35391,9 +35641,9 @@ function createStatusCommand() {
|
|
|
35391
35641
|
|
|
35392
35642
|
// src/cli/commands/update.ts
|
|
35393
35643
|
init_esm_shims();
|
|
35394
|
-
import { Command as
|
|
35644
|
+
import { Command as Command23 } from "commander";
|
|
35395
35645
|
function createUpdateCommand() {
|
|
35396
|
-
return new
|
|
35646
|
+
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
35647
|
try {
|
|
35398
35648
|
const report = await new FrameworkUpdater().run(options.projectRoot);
|
|
35399
35649
|
if (!options.silent) {
|
|
@@ -35417,7 +35667,7 @@ function createUpdateCommand() {
|
|
|
35417
35667
|
|
|
35418
35668
|
// src/cli/program.ts
|
|
35419
35669
|
function createProgram() {
|
|
35420
|
-
const program = new
|
|
35670
|
+
const program = new Command24();
|
|
35421
35671
|
program.name("paqad-ai").description("AI Agency Framework for software agencies").version(VERSION).showSuggestionAfterError(true);
|
|
35422
35672
|
program.addCommand(createInstallCommand());
|
|
35423
35673
|
program.addCommand(createCapabilitiesCommand());
|
|
@@ -35440,6 +35690,7 @@ function createProgram() {
|
|
|
35440
35690
|
program.addCommand(createRagEvidenceCommand());
|
|
35441
35691
|
program.addCommand(createUpdateCommand());
|
|
35442
35692
|
program.addCommand(createPatternsCommand());
|
|
35693
|
+
program.addCommand(createStageCommand());
|
|
35443
35694
|
program.addCommand(createStatusCommand());
|
|
35444
35695
|
return program;
|
|
35445
35696
|
}
|