@shardworks/astrolabe-apparatus 0.1.229 → 0.1.231

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 CHANGED
@@ -64,7 +64,7 @@ interface PlanDoc {
64
64
  scope?: ScopeItem[]; // What's in and what's out
65
65
  decisions?: Decision[]; // Architectural/design decisions with options
66
66
  spec?: string; // The generated specification (implementation brief + task manifest)
67
- generatedWritId?: string; // ID of the generated mandate/configured writ type
67
+ generatedWritId?: string; // ID of the generated mandate
68
68
  createdAt: string;
69
69
  updatedAt: string;
70
70
  }
@@ -88,7 +88,6 @@ Add an `astrolabe` section to `guild.json` to configure behaviour:
88
88
  ```json
89
89
  {
90
90
  "astrolabe": {
91
- "generatedWritType": "mandate",
92
91
  "patronRole": "my-plugin.patron"
93
92
  }
94
93
  }
@@ -96,7 +95,6 @@ Add an `astrolabe` section to `guild.json` to configure behaviour:
96
95
 
97
96
  | Field | Type | Default | Description |
98
97
  |---|---|---|---|
99
- | `generatedWritType` | `string` | `"mandate"` | Writ type posted by the spec-writer engine |
100
98
  | `patronRole` | `string` | `""` (unset) | Qualified role name of the Patron Anima consulted before decision-review. When unset or empty, the `patron-anima` engine no-ops and decision-review behaves exactly as it did before the engine existed. |
101
99
 
102
100
  ## Support Kit
@@ -1 +1 @@
1
- {"version":3,"file":"spec-publish.d.ts","sourceRoot":"","sources":["../../src/engines/spec-publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAqC,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,CA+DvF"}
1
+ {"version":3,"file":"spec-publish.d.ts","sourceRoot":"","sources":["../../src/engines/spec-publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAqC,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,CA4DvF"}
@@ -38,11 +38,9 @@ export function createSpecPublishEngine(getPlansBook) {
38
38
  const clerk = guild().apparatus('clerk');
39
39
  // Read the brief writ for its title
40
40
  const briefWrit = await clerk.show(planId);
41
- // Resolve generated writ type from config
42
- const generatedWritType = guild().guildConfig().astrolabe?.generatedWritType ?? 'mandate';
43
41
  // Post the mandate with the full spec verbatim (task-manifest included if present).
44
42
  const generatedWrit = await clerk.post({
45
- type: generatedWritType,
43
+ type: 'mandate',
46
44
  title: briefWrit.title,
47
45
  body: plan.spec,
48
46
  codex: plan.codex,
@@ -1 +1 @@
1
- {"version":3,"file":"spec-publish.js","sourceRoot":"","sources":["../../src/engines/spec-publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAM/C,MAAM,UAAU,uBAAuB,CAAC,YAAiC;IACvE,OAAO;QACL,EAAE,EAAE,wBAAwB;QAE5B,KAAK,CAAC,GAAG,CACP,MAA+B,EAC/B,QAA0B;YAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgB,CAAC;YACvC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAE5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;YACjD,CAAC;YAED,kBAAkB;YAClB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,CAAC,MAAM,eAAe,MAAM,IAAI,CAC9F,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,2DAA2D,CAC3E,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,SAAS,CAAW,OAAO,CAAC,CAAC;YAEnD,oCAAoC;YACpC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE3C,0CAA0C;YAC1C,MAAM,iBAAiB,GAAG,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,iBAAiB,IAAI,SAAS,CAAC;YAE1F,oFAAoF;YACpF,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;gBACrC,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YAEH,0DAA0D;YAC1D,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YAEtD,iBAAiB;YACjB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;gBACvB,eAAe,EAAE,aAAa,CAAC,EAAE;gBACjC,MAAM,EAAE,WAAW;gBACnB,SAAS,EAAE,GAAG;aACf,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,EAAE,EAAE;aAC9C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"spec-publish.js","sourceRoot":"","sources":["../../src/engines/spec-publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAM/C,MAAM,UAAU,uBAAuB,CAAC,YAAiC;IACvE,OAAO;QACL,EAAE,EAAE,wBAAwB;QAE5B,KAAK,CAAC,GAAG,CACP,MAA+B,EAC/B,QAA0B;YAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgB,CAAC;YACvC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAE5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;YACjD,CAAC;YAED,kBAAkB;YAClB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,CAAC,MAAM,eAAe,MAAM,IAAI,CAC9F,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5D,MAAM,IAAI,KAAK,CACb,SAAS,MAAM,2DAA2D,CAC3E,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,SAAS,CAAW,OAAO,CAAC,CAAC;YAEnD,oCAAoC;YACpC,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE3C,oFAAoF;YACpF,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;gBACrC,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;YAEH,0DAA0D;YAC1D,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;YAEtD,iBAAiB;YACjB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;gBACvB,eAAe,EAAE,aAAa,CAAC,EAAE;gBACjC,MAAM,EAAE,WAAW;gBACnB,SAAS,EAAE,GAAG;aACf,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,CAAC,EAAE,EAAE;aAC9C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -23,7 +23,7 @@ export interface PlanDoc {
23
23
  decisions?: Decision[];
24
24
  /** The generated specification. */
25
25
  spec?: string;
26
- /** The writ ID of the generated mandate (or configured type). */
26
+ /** The writ ID of the generated mandate. */
27
27
  generatedWritId?: string;
28
28
  createdAt: string;
29
29
  updatedAt: string;
@@ -90,8 +90,6 @@ export interface PlanFilters {
90
90
  offset?: number;
91
91
  }
92
92
  export interface AstrolabeConfig {
93
- /** The writ type posted by the spec-writer engine. Default: 'mandate'. */
94
- generatedWritType?: string;
95
93
  /**
96
94
  * Qualified role name of the Patron Anima consulted by the
97
95
  * `astrolabe.patron-anima` engine before `decision-review`. When unset
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAIpG,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,UAAU,CAAC;IAGnB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,mDAAmD;IACnD,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IAGvB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,WAAW;QACnB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;CACF;AAID,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,yEAAyE;IACzE,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,kFAAkF;IAClF,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardworks/astrolabe-apparatus",
3
- "version": "0.1.229",
3
+ "version": "0.1.231",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,17 +20,17 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "zod": "4.3.6",
23
- "@shardworks/stacks-apparatus": "0.1.229",
24
- "@shardworks/tools-apparatus": "0.1.229",
25
- "@shardworks/clerk-apparatus": "0.1.229",
26
- "@shardworks/fabricator-apparatus": "0.1.229",
27
- "@shardworks/spider-apparatus": "0.1.229",
28
- "@shardworks/loom-apparatus": "0.1.229",
29
- "@shardworks/animator-apparatus": "0.1.229"
23
+ "@shardworks/stacks-apparatus": "0.1.231",
24
+ "@shardworks/tools-apparatus": "0.1.231",
25
+ "@shardworks/clerk-apparatus": "0.1.231",
26
+ "@shardworks/spider-apparatus": "0.1.231",
27
+ "@shardworks/fabricator-apparatus": "0.1.231",
28
+ "@shardworks/animator-apparatus": "0.1.231",
29
+ "@shardworks/loom-apparatus": "0.1.231"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "25.5.0",
33
- "@shardworks/nexus-core": "0.1.229"
33
+ "@shardworks/nexus-core": "0.1.231"
34
34
  },
35
35
  "files": [
36
36
  "dist",
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  "scripts": {
44
44
  "build": "tsc",
45
- "test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts'",
45
+ "test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --test 'src/**/*.test.ts' 'pages/**/*.test.js'",
46
46
  "typecheck": "tsc --noEmit"
47
47
  }
48
48
  }
@@ -307,10 +307,10 @@
307
307
  detailTitle.textContent = 'Plan: ' + plan.id;
308
308
 
309
309
  // Metadata card
310
- var briefLink = '<a href="/pages/clerk/?writ=' + encodeURIComponent(plan.id) + '">' + esc(plan.id) + '</a>';
310
+ var briefLink = '<a href="/pages/writs/?writ=' + encodeURIComponent(plan.id) + '">' + esc(plan.id) + '</a>';
311
311
  var mandateHtml = '';
312
312
  if (plan.generatedWritId) {
313
- mandateHtml = '<dt>Mandate Writ</dt><dd><a href="/pages/clerk/?writ=' +
313
+ mandateHtml = '<dt>Mandate Writ</dt><dd><a href="/pages/writs/?writ=' +
314
314
  encodeURIComponent(plan.generatedWritId) + '">' + esc(plan.generatedWritId) + '</a></dd>';
315
315
  }
316
316
 
@@ -10,6 +10,12 @@
10
10
 
11
11
  import { describe, it } from 'node:test';
12
12
  import assert from 'node:assert/strict';
13
+ import { readFileSync } from 'node:fs';
14
+ import { resolve, dirname } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const astrolabeJs = readFileSync(resolve(__dirname, 'astrolabe.js'), 'utf-8');
13
19
 
14
20
  // ── Extracted pure functions (identical to astrolabe.js) ─────────────
15
21
 
@@ -422,3 +428,34 @@ describe('renderDecisionsTable()', () => {
422
428
  assert.ok(!html.includes('<script>'));
423
429
  });
424
430
  });
431
+
432
+ describe('astrolabe.js plan-detail writ cross-link URL', () => {
433
+ // Regression guard: the plan-detail brief-writ and mandate-writ anchors
434
+ // historically targeted '/pages/clerk/?writ=…', but no plugin registers
435
+ // a page with id 'clerk' — the Clerk's writs page is registered with id
436
+ // 'writs' and served at '/pages/writs/'. That produced a bare 404 on
437
+ // every click. Pin the canonical URL shape and forbid the broken one.
438
+
439
+ it('writ deep-links target the canonical Clerk writs page path', () => {
440
+ assert.match(
441
+ astrolabeJs,
442
+ /\/pages\/writs\/\?writ=/,
443
+ 'writ deep-links must target /pages/writs/?writ=',
444
+ );
445
+ assert.doesNotMatch(
446
+ astrolabeJs,
447
+ /\/pages\/clerk\/\?writ=/,
448
+ 'writ deep-links must NOT target the broken /pages/clerk/?writ= path',
449
+ );
450
+ });
451
+
452
+ it('both plan-detail writ anchors (brief and mandate) use the canonical path', () => {
453
+ // The plan-detail view emits two writ anchors: the brief-writ link and
454
+ // the (optional) mandate-writ link. Both must use the canonical shape.
455
+ var matches = astrolabeJs.match(/\/pages\/writs\/\?writ=/g) || [];
456
+ assert.ok(
457
+ matches.length >= 2,
458
+ 'expected at least 2 canonical /pages/writs/?writ= links (brief + mandate), found ' + matches.length,
459
+ );
460
+ });
461
+ });