paqad-ai 1.22.0 → 1.22.2

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # paqad-ai
2
2
 
3
+ ## 1.22.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#177](https://github.com/Eliyce/paqad-ai/pull/177) [`ea8c367`](https://github.com/Eliyce/paqad-ai/commit/ea8c36722c84ac82c486e5dbaf9dad0cc9d9bac5) Thanks [@HLasani](https://github.com/HLasani)! - Fix the AI bill of materials on the dashboard.
8
+
9
+ Two problems made the BOM unreadable. First, `git status --short` parsing left-trimmed each line before slicing the status columns, which dropped the first character of every worktree-only changed path (`package.json` became `ackage.json`). That corrupted the BOM component names, their file digests, and the change-completeness gate messages. Second, the dashboard BOM panel only showed a file count, never the files themselves. The panel now lists every attested file with its SHA-256 digest, and shows a clear empty state when the latest verified change touched no files.
10
+
11
+ - [#177](https://github.com/Eliyce/paqad-ai/pull/177) [`ea8c367`](https://github.com/Eliyce/paqad-ai/commit/ea8c36722c84ac82c486e5dbaf9dad0cc9d9bac5) Thanks [@HLasani](https://github.com/HLasani)! - Restore the executable bit on the installed runtime hooks and scripts.
12
+
13
+ The package is published with `changeset publish`, which packs the tarball with pnpm. pnpm normalises every file mode to `0644` and drops the executable bit (npm preserves it), so on an installed copy the host agent could not run any runtime hook: invoking `~/.paqad-ai/current/hooks/verification-completion.mjs` failed with "permission denied". The visible symptom was that the verification backstop never fired for onboarded projects, so the evidence ledger, receipts, AI-BOM, and the local dashboard data were never produced. A `postinstall` step now re-adds the executable bit on every install and update, with no action required from the user.
14
+
15
+ ## 1.22.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [#174](https://github.com/Eliyce/paqad-ai/pull/174) [`8ad856b`](https://github.com/Eliyce/paqad-ai/commit/8ad856b5c02d7a32ccc7113aa811f2777a5e3985) Thanks [@HLasani](https://github.com/HLasani)! - Collapse the in-chat narration contract in provider entry files to a one-line pointer ([#173](https://github.com/Eliyce/paqad-ai/issues/173)). The full voice spec stays in the canonical `.paqad/narration-contract.md`; the entry files (CLAUDE.md, AGENTS.md, and every adapter) now carry only the heading plus a pointer line, matching the Decision Pause Contract shape. `paqad refresh --providers` rewrites already-onboarded projects down to the pointer.
20
+
3
21
  ## 1.22.0
4
22
 
5
23
  ### Minor Changes
package/dist/cli/index.js CHANGED
@@ -7486,72 +7486,6 @@ var TemplateEngine = class {
7486
7486
  // src/adapters/shared/narration-contract.ts
7487
7487
  init_esm_shims();
7488
7488
 
7489
- // src/core/constants/paqad-voice.ts
7490
- init_esm_shims();
7491
- var PAQAD_STATUS_GLYPH = {
7492
- /** Passed, good, on track. */
7493
- good: "\u{1F7E2}",
7494
- /** Failed, blocking. */
7495
- failed: "\u{1F534}",
7496
- /** Inconclusive, needs a look, over-trust risk. */
7497
- needsLook: "\u{1F7E1}",
7498
- /** Not run, not applicable. */
7499
- skipped: "\u26AA"
7500
- };
7501
- var PAQAD_STATUS_LABEL = {
7502
- good: "good",
7503
- failed: "failed",
7504
- needsLook: "needs a look",
7505
- skipped: "skipped"
7506
- };
7507
- var PAQAD_VERDICT = {
7508
- pass: "Safe to merge",
7509
- fail: "Needs your attention",
7510
- inconclusive: "Inconclusive"
7511
- };
7512
- var PAQAD_FRAME_LEAD = "**\u25B8 paqad**";
7513
- var PAQAD_FRAME_SEP = "\xB7";
7514
- function paqadFrameLead(label) {
7515
- return `${PAQAD_FRAME_LEAD} ${PAQAD_FRAME_SEP} ${label}`;
7516
- }
7517
- function paqadGlyphLegend() {
7518
- return Object.keys(PAQAD_STATUS_GLYPH).map((kind) => `${PAQAD_STATUS_GLYPH[kind]} ${PAQAD_STATUS_LABEL[kind]}`).join(` ${PAQAD_FRAME_SEP} `);
7519
- }
7520
- var PAQAD_TERM_TRANSLATIONS = [
7521
- {
7522
- term: "classification",
7523
- plain: "I read your request and judged how risky it is."
7524
- },
7525
- {
7526
- term: "lane / routing",
7527
- plain: "I picked the path: a quick path for small changes, the full path (spec \u2192 build \u2192 verify) for risky ones."
7528
- },
7529
- {
7530
- term: "requirement derivation",
7531
- plain: "I worked out what this actually needs to do before building it."
7532
- },
7533
- {
7534
- term: "verification gates",
7535
- plain: "I ran the safety checks for you before calling this done."
7536
- },
7537
- {
7538
- term: "mutation testing",
7539
- plain: "I double-checked your tests actually catch bugs, not just run."
7540
- },
7541
- {
7542
- term: "quality ratchet",
7543
- plain: "I made sure nothing slipped below the quality bar you'd already set."
7544
- },
7545
- {
7546
- term: "traceability",
7547
- plain: "I tied each requirement to the test that proves it."
7548
- },
7549
- {
7550
- term: "decision pause",
7551
- plain: "I hit a real choice that's yours to make, so I stopped to ask."
7552
- }
7553
- ];
7554
-
7555
7489
  // src/adapters/shared/provider-entry-contract.ts
7556
7490
  init_esm_shims();
7557
7491
 
@@ -7605,27 +7539,6 @@ var POINTER_BODY2 = "See `.paqad/narration-contract.md` for the full voice spec,
7605
7539
  function buildNarrationContractSection() {
7606
7540
  return `${HEADING}
7607
7541
 
7608
- paqad runs the orchestration behind your agent: it classifies the request, routes it to a lane, derives the requirements, runs the verification gates, and holds the quality ratchet. Make that work visible so the developer feels the layer working for them. Speak as paqad \u2014 first person, addressed to the developer \u2014 not as the model narrating itself.
7609
-
7610
- Speak only at substantive transitions, never on every line:
7611
-
7612
- - **Handshake (once per session):** name paqad and frame it as the layer in charge. This is the one full-name anchor.
7613
- - **On a real decision:** when you classify, pick a lane, derive requirements, or run/skip a gate. One compact line \u2014 the proactive choice you made, not an echo of the prompt.
7614
- - **On a verdict:** when verification, mutation, or the quality ratchet produces a result, especially a problem you caught. Honest and plain.
7615
- - **On a pause:** when the Decision Pause Contract fires.
7616
-
7617
- Voice: first person, framing the work as done on the developer's behalf ("checked for you", "caught this before it shipped"). Translate every internal term to plain language \u2014 no jargon. Be honest on bad outcomes: never dress up a failure, and surface caught problems as prominently as green checks so trust stays calibrated, never inflated. Name "paqad" about once per session plus once per genuinely valuable verdict; everywhere else let the status frame below carry the recognition.
7618
-
7619
- Format \u2014 a markdown status block. Rely on markdown structure (headings, bold, blockquotes, task lists, emoji), never ANSI colour, and keep every line legible with the glyphs stripped:
7620
-
7621
- \`\`\`
7622
- ${paqadFrameLead("<short label>")}
7623
- > One plain sentence, on the developer's behalf.
7624
- > - \u{1F7E2} a status line \u2014 the words carry the meaning, the glyph only reinforces it
7625
- \`\`\`
7626
-
7627
- Status glyphs carry fixed, reserved meaning, reused from the paqad evidence comment: ${paqadGlyphLegend()}.
7628
-
7629
7542
  ${POINTER_BODY2}`;
7630
7543
  }
7631
7544
  function extractNarrationContractSection(content) {
@@ -24579,6 +24492,71 @@ function writeDecisionPauseContractDocument(projectRoot) {
24579
24492
  init_esm_shims();
24580
24493
  init_paths();
24581
24494
  import { join as join80 } from "path";
24495
+
24496
+ // src/core/constants/paqad-voice.ts
24497
+ init_esm_shims();
24498
+ var PAQAD_STATUS_GLYPH = {
24499
+ /** Passed, good, on track. */
24500
+ good: "\u{1F7E2}",
24501
+ /** Failed, blocking. */
24502
+ failed: "\u{1F534}",
24503
+ /** Inconclusive, needs a look, over-trust risk. */
24504
+ needsLook: "\u{1F7E1}",
24505
+ /** Not run, not applicable. */
24506
+ skipped: "\u26AA"
24507
+ };
24508
+ var PAQAD_STATUS_LABEL = {
24509
+ good: "good",
24510
+ failed: "failed",
24511
+ needsLook: "needs a look",
24512
+ skipped: "skipped"
24513
+ };
24514
+ var PAQAD_VERDICT = {
24515
+ pass: "Safe to merge",
24516
+ fail: "Needs your attention",
24517
+ inconclusive: "Inconclusive"
24518
+ };
24519
+ var PAQAD_FRAME_LEAD = "**\u25B8 paqad**";
24520
+ var PAQAD_FRAME_SEP = "\xB7";
24521
+ function paqadFrameLead(label) {
24522
+ return `${PAQAD_FRAME_LEAD} ${PAQAD_FRAME_SEP} ${label}`;
24523
+ }
24524
+ var PAQAD_TERM_TRANSLATIONS = [
24525
+ {
24526
+ term: "classification",
24527
+ plain: "I read your request and judged how risky it is."
24528
+ },
24529
+ {
24530
+ term: "lane / routing",
24531
+ plain: "I picked the path: a quick path for small changes, the full path (spec \u2192 build \u2192 verify) for risky ones."
24532
+ },
24533
+ {
24534
+ term: "requirement derivation",
24535
+ plain: "I worked out what this actually needs to do before building it."
24536
+ },
24537
+ {
24538
+ term: "verification gates",
24539
+ plain: "I ran the safety checks for you before calling this done."
24540
+ },
24541
+ {
24542
+ term: "mutation testing",
24543
+ plain: "I double-checked your tests actually catch bugs, not just run."
24544
+ },
24545
+ {
24546
+ term: "quality ratchet",
24547
+ plain: "I made sure nothing slipped below the quality bar you'd already set."
24548
+ },
24549
+ {
24550
+ term: "traceability",
24551
+ plain: "I tied each requirement to the test that proves it."
24552
+ },
24553
+ {
24554
+ term: "decision pause",
24555
+ plain: "I hit a real choice that's yours to make, so I stopped to ask."
24556
+ }
24557
+ ];
24558
+
24559
+ // src/onboarding/narration-contract-writer.ts
24582
24560
  function buildNarrationContractDocument() {
24583
24561
  const glyphRows = Object.keys(PAQAD_STATUS_GLYPH).map((kind) => `| ${PAQAD_STATUS_GLYPH[kind]} | ${PAQAD_STATUS_LABEL[kind]} |`).join("\n");
24584
24562
  const translationRows = PAQAD_TERM_TRANSLATIONS.map((t) => `| ${t.term} | ${t.plain} |`).join(
@@ -24590,7 +24568,7 @@ function buildNarrationContractDocument() {
24590
24568
 
24591
24569
  paqad runs the orchestration behind the coding agent \u2014 classifying the request, routing it to a lane, deriving requirements, running the verification gates, holding the quality ratchet, writing the evidence ledger. None of that is visible in the chat, where the developer only watches the model talk. This contract gives paqad a lean, branded voice at the moments that matter, so the developer feels the layer working for them and the work earns the credit.
24592
24570
 
24593
- This is the canonical, full spec. A lean copy of the operative rules is rendered into every provider entry file so the agent has them in context every turn; the complete detail lives here.
24571
+ This is the canonical, full spec. Every provider entry file carries a one-line pointer to this document; the complete detail lives here.
24594
24572
 
24595
24573
  ## When paqad speaks (cadence)
24596
24574
 
@@ -27122,18 +27100,21 @@ async function readGitStatusFiles(projectRoot) {
27122
27100
  return [];
27123
27101
  }
27124
27102
  return normalizePaths(
27125
- result.stdout.split("\n").map((line) => line.trim()).filter(Boolean).map(parseGitStatusPath).filter((value) => value !== null)
27103
+ result.stdout.split("\n").map(parseGitStatusPath).filter((value) => value !== null)
27126
27104
  );
27127
27105
  } catch {
27128
27106
  return [];
27129
27107
  }
27130
27108
  }
27131
27109
  function parseGitStatusPath(line) {
27132
- const trimmed = line.trim();
27133
- if (trimmed.length < 4) {
27110
+ const stripped = line.replace(/\r$/, "");
27111
+ if (stripped.length < 4) {
27112
+ return null;
27113
+ }
27114
+ const payload = stripped.slice(3).trim();
27115
+ if (payload.length === 0) {
27134
27116
  return null;
27135
27117
  }
27136
- const payload = trimmed.slice(3).trim();
27137
27118
  if (payload.includes(" -> ")) {
27138
27119
  return (
27139
27120
  /* v8 ignore next */
@@ -35055,7 +35036,7 @@ init_esm_shims();
35055
35036
  init_esm_shims();
35056
35037
 
35057
35038
  // src/index.ts
35058
- var VERSION = "1.22.0";
35039
+ var VERSION = "1.22.2";
35059
35040
 
35060
35041
  // src/cli/commands/audit.ts
35061
35042
  init_esm_shims();