@archme/cli 0.14.2 → 0.14.4

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/dist/cli.js CHANGED
@@ -15165,6 +15165,21 @@ var init_componentOrganization = __esm({
15165
15165
  }
15166
15166
  });
15167
15167
 
15168
+ // ../shared/componentDescription.ts
15169
+ var COMPONENT_DESCRIPTION_GUIDANCE;
15170
+ var init_componentDescription = __esm({
15171
+ "../shared/componentDescription.ts"() {
15172
+ COMPONENT_DESCRIPTION_GUIDANCE = `Component description:
15173
+ - **Say what the component is for, in general terms.** One to three sentences on its job in the system: why it exists, not how it works.
15174
+ - Good: "Keeps each order's payment status in step with Stripe."
15175
+ - Bad: "Receives the Stripe webhook, verifies the signature, looks up the order by payment intent, updates its status, retries on a conflict and emits order.paid."
15176
+ - **It is not a sequence.** Steps, their order, triggers, retries, timings and branches belong in a story's \`sequence\`. A change to how a flow runs is a sequence edit, never a description edit.
15177
+ - **It is not a data contract.** Fields, parameters, return shapes and columns belong in \`schema\`. A change to the data is a schema edit.
15178
+ - **Other detail stays out of the graph.** Caveats, derivations, constraints and DDL live in the code, which the component's anchors link to.
15179
+ - **Edit a description only when the component's job changes.** A fix or an internal change leaves it alone, and never rewrite an existing description just to restyle it: every edit lands in someone's diff.`;
15180
+ }
15181
+ });
15182
+
15168
15183
  // ../shared/scanPrompts.ts
15169
15184
  function buildStoryCoverageGate(opts) {
15170
15185
  const preWrite = opts.noChangeSignal ? `
@@ -15246,6 +15261,7 @@ var init_scanPrompts = __esm({
15246
15261
  init_sequenceWording();
15247
15262
  init_leafEndpoints();
15248
15263
  init_componentOrganization();
15264
+ init_componentDescription();
15249
15265
  BUILD_METHODOLOGY = `You are a build sub-agent. You are part of a multi-agent system that builds a comprehensive visual architecture of a codebase \u2014 components, connections, and user stories that trace data flow end-to-end. Your role is to translate research findings into actual architecture: creating components backed by real code references, wiring connections between them, and building story sequence diagrams that trace how data flows through the system.
15250
15266
 
15251
15267
  # Rules
@@ -15320,6 +15336,8 @@ Component kind:
15320
15336
 
15321
15337
  ${COMPONENT_ORGANIZATION_GUIDANCE}
15322
15338
 
15339
+ ${COMPONENT_DESCRIPTION_GUIDANCE}
15340
+
15323
15341
  Component schema:
15324
15342
  - Defines the data contract for interface children (input/output components)
15325
15343
  - Compact format: { field: type, field?: type, field!: type, nested: { ... }, array: type[], ... }
@@ -15335,14 +15353,14 @@ Component schema:
15335
15353
  - "{ user: { id: string, name?: string }, roles: string[] }" - nested object and array
15336
15354
  - "{ auth: token, ... }" - allow additional fields
15337
15355
  - MUST be this compact STRING \u2014 never a JSON object. A whole-schema trailing "[]" ("{ ... }[]") means "an array of that shape".
15338
- - SHAPE ONLY \u2014 no comments or prose. The string must START with "{" and END with "}" (or "}[]"). Do NOT append a "// ..." comment, and do NOT wrap it in prose (e.g. "TypeName (path): { ... }. Note: ..."). Any explanation \u2014 how a key is derived, what a field encodes, caveats \u2014 goes in the component description or context, never in schema. A schema with a trailing comment or surrounding prose is unparseable and is rejected on write (the ONE exception is schemaKind: "unstructured" \u2014 see below).
15356
+ - SHAPE ONLY \u2014 no comments or prose. The string must START with "{" and END with "}" (or "}[]"). Do NOT append a "// ..." comment, and do NOT wrap it in prose (e.g. "TypeName (path): { ... }. Note: ..."). Any explanation \u2014 how a key is derived, what a field encodes, caveats \u2014 stays out of schema and out of the description: the code holds it. A schema with a trailing comment or surrounding prose is unparseable and is rejected on write (the ONE exception is schemaKind: "unstructured" \u2014 see below).
15339
15357
 
15340
15358
  Data-store (table) schema:
15341
15359
  - For a persisted store (a DB table/collection), set schemaKind: "table" and schemaName (e.g. "cards") on the component, and tag key columns inline:
15342
15360
  - @pk : primary-key column (e.g. "id: uuid @pk")
15343
15361
  - @fk(target) : foreign-key column referencing target (e.g. "user_id?: uuid @fk(auth.users.id)")
15344
15362
  - Example: schemaKind: "table", schemaName: "cards", schema: "{ id: uuid @pk, user_id?: uuid @fk(auth.users.id), text: text, created_at: timestamptz }"
15345
- - Keep DDL, RLS policies, and indexes OUT of schema \u2014 those are code (the component's anchored migration) or belong in the component description/context. The graph holds the column shape + keys only.
15363
+ - Keep DDL, RLS policies, and indexes OUT of schema \u2014 those are code (the component's anchored migration). The graph holds the column shape + keys only.
15346
15364
 
15347
15365
  Unstructured (freeform) schema:
15348
15366
  - STRONGLY PREFER "params" (a contract) or "table" (a store) whenever the data has ANY real field shape \u2014 decompose it into fields with types rather than dumping prose. Use schemaKind: "unstructured" ONLY for data that has no field shape to capture: binary blobs, uploaded/attached files, images/media, raw byte buffers, encoded/encrypted payloads, or a genuinely opaque third-party payload whose shape you can't or shouldn't enumerate.
@@ -15350,7 +15368,7 @@ Unstructured (freeform) schema:
15350
15368
 
15351
15369
  Pre-existing unparseable schema:
15352
15370
  - Legacy components can carry a schema that predates the shape-only rule \u2014 DDL ("id uuid PK, org_id uuid, ..."), a signature ("(a, b) -> c"), a JSON object, or prose. It is a capture defect, not a contract, and echoing it back rejects your whole write.
15353
- - When a component you are ALREADY touching has one, repair it FIRST as a separate phase: "structural" write (set enables_change naming the diff edit it unblocks), then apply your diff edits on top. Decompose it into params/table fields and move the prose \u2014 constraints, CHECK enums, derivations, return types \u2014 into the component description.
15371
+ - When a component you are ALREADY touching has one, repair it FIRST as a separate phase: "structural" write (set enables_change naming the diff edit it unblocks), then apply your diff edits on top. Decompose it into params/table fields and drop the prose \u2014 constraints, CHECK enums, derivations, return types \u2014 which the code already holds.
15354
15372
  - Scope it to the components this change already touches. Do NOT go hunting for malformed schemas elsewhere in the graph; an unrelated backfill is rejected on the diff path.
15355
15373
 
15356
15374
  Component annotations:
@@ -16042,6 +16060,15 @@ var init_proposalAbout = __esm({
16042
16060
  }
16043
16061
  });
16044
16062
 
16063
+ // ../shared/proposalDone.ts
16064
+ function isProposalDone(doneOverride, realizationState) {
16065
+ return doneOverride ?? realizationState === "closed";
16066
+ }
16067
+ var init_proposalDone = __esm({
16068
+ "../shared/proposalDone.ts"() {
16069
+ }
16070
+ });
16071
+
16045
16072
  // ../shared/boardTriage.ts
16046
16073
  function flatten(stories, out = []) {
16047
16074
  for (const s of stories) {
@@ -16074,7 +16101,7 @@ function aboutThisRepo(about, scope) {
16074
16101
  }
16075
16102
  function selectTriageCandidates(rows, scope, limit = TRIAGE_CANDIDATE_LIMIT) {
16076
16103
  return rows.filter(
16077
- (r) => r.kind === "proposal" && !TERMINAL.has(r.realization_state ?? "") && r.review_state !== "rejected" && aboutThisRepo(aboutFromColumns(r), scope)
16104
+ (r) => r.kind === "proposal" && !isProposalDone(r.done_override, r.realization_state) && r.realization_state !== "abandoned" && r.review_state !== "rejected" && aboutThisRepo(aboutFromColumns(r), scope)
16078
16105
  ).sort((a2, b) => b.updated_at.localeCompare(a2.updated_at)).slice(0, limit).map((r) => ({
16079
16106
  id: r.id,
16080
16107
  title: r.title,
@@ -16083,14 +16110,14 @@ function selectTriageCandidates(rows, scope, limit = TRIAGE_CANDIDATE_LIMIT) {
16083
16110
  about: aboutFromColumns(r)
16084
16111
  }));
16085
16112
  }
16086
- var TRIAGE_CANDIDATE_LIMIT, TERMINAL;
16113
+ var TRIAGE_CANDIDATE_LIMIT;
16087
16114
  var init_boardTriage = __esm({
16088
16115
  "../shared/boardTriage.ts"() {
16089
16116
  init_proposalAbout();
16117
+ init_proposalDone();
16090
16118
  init_repoContainer();
16091
16119
  init_waypoints();
16092
16120
  TRIAGE_CANDIDATE_LIMIT = 40;
16093
- TERMINAL = /* @__PURE__ */ new Set(["closed", "abandoned"]);
16094
16121
  }
16095
16122
  });
16096
16123
 
@@ -21593,7 +21620,7 @@ ${PHASE_GUIDANCE}
21593
21620
  You MUST exit with one of two positive signals \u2014 never exit silently:
21594
21621
 
21595
21622
  - **Architectural change.** Call \`update_architecture\` (one or more times) with your edits. The write itself is the signal.
21596
- - **No change.** If after reading the diff and the affected stories/components you determine nothing in the diagram needs to update, call \`report_no_change\` with a one-line \`reason\` (e.g. "doc-only diff", "test-only change covered by existing story"). This is REQUIRED \u2014 exiting without calling either tool is treated as a tool-surface failure and the job is retried.
21623
+ - **No change.** If after reading the diff and the affected stories/components you determine nothing in the diagram needs to update, call \`report_no_change\` with a one-line \`reason\` (e.g. "doc-only diff", "test-only change covered by existing story"). If the only edit you would make is to a component's \`description\`, that is no change either: call \`report_no_change\` instead of writing it. This is REQUIRED \u2014 exiting without calling either tool is treated as a tool-surface failure and the job is retried.
21597
21624
 
21598
21625
  ${walkthroughSection}## Feedback
21599
21626
 
@@ -22102,7 +22129,7 @@ async function completeClaudeRun(ctx, job, deviceId, run) {
22102
22129
  );
22103
22130
  }
22104
22131
  async function loadTriageProposals(client, projectId) {
22105
- const { data, error } = await client.from("proposals").select("id, kind, title, description, review_state, realization_state, about_component, about_story, about_repo, updated_at").eq("project_id", projectId).eq("kind", "proposal").not("realization_state", "in", "(closed,abandoned)").order("updated_at", { ascending: false }).limit(500);
22132
+ const { data, error } = await client.from("proposals").select("id, kind, title, description, review_state, realization_state, done_override, about_component, about_story, about_repo, updated_at").eq("project_id", projectId).eq("kind", "proposal").not("realization_state", "in", "(closed,abandoned)").order("updated_at", { ascending: false }).limit(500);
22106
22133
  if (error) return null;
22107
22134
  return data ?? [];
22108
22135
  }
@@ -23250,7 +23277,7 @@ Rules:
23250
23277
  A data-shape change with unchanged topology is still an architectural change \u2014 the same components can talk in the same order while the shape of the data on the wire changes. If this change adds, removes, or retypes a **DB column**, a **function/RPC parameter**, or a **response/return field**, update the \`schema\` of the affected storage component (table, RPC, queue, any persistence layer) and the **input/output interface children** the data flows through. Compact format: \`{ field: type, field?: type, field!: generated, arr: type[], ... }\`. For a **persisted table**, set \`schemaKind: "table"\` + \`schemaName\` on the component and tag key columns inline (\`id: uuid @pk\`, \`user_id?: uuid @fk(auth.users.id)\`); keep DDL, RLS policies, and indexes OUT of \`schema\` \u2014 those are code (the anchored migration). Match the code exactly \u2014 do NOT invent fields the code doesn't have; a \`schema\` more complete than the code can prove is over-claiming.
23251
23278
 
23252
23279
  ## Behaviour at a step
23253
- A behaviour change with unchanged participants is still an architectural change: the same components talk in the same order, but what a step does or guarantees has changed (the caller's real IP now reaches the backend, a failed call is now retried, a limit is now enforced). Show it in the \`sequence\` of the story that draws that step \u2014 reword that arrow, or add a short Note at that step when no arrow can carry it (see Sequence wording). A component \`description\` edit on its own barely shows in review, so it does not stand in for the sequence edit.
23280
+ A behaviour change with unchanged participants is still an architectural change: the same components talk in the same order, but what a step does or guarantees has changed (the caller's real IP now reaches the backend, a failed call is now retried, a limit is now enforced). Show it in the \`sequence\` of the story that draws that step \u2014 reword that arrow, or add a short Note at that step when no arrow can carry it (see Sequence wording). A component \`description\` says what the component is for, not what its steps do (see Component description), so editing one does not stand in for the sequence edit.
23254
23281
 
23255
23282
  ## Draft Story Guidance
23256
23283
  \`draft: true\` is a transient build mechanic, not a deliverable: it skips sequence validation while a story is being assembled, and a parent's draft flag propagates to all descendants (suppressing \`autoCreateConnectionsFromStories\`). Feature-group parent stories that have real, sequenced children are NOT drafts. You may set it mid-run to defer validation while assembling a story, but finish the run with zero drafts you created or touched: give each a real sequence and set \`draft: false\`, or remove it. Pre-existing drafts you didn't touch are not yours to sweep.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archme/cli",
3
- "version": "0.14.2",
3
+ "version": "0.14.4",
4
4
  "description": "Map your codebase into a living architecture diagram: run `archme init` in a repo to scan it, `archme daemon start` to keep it current on every commit.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "image": "ghcr.io/architectme/archme-job",
3
- "digest": "sha256:e65cbf5dbcd3e9289e54c140922a98904ce2c7fa28402bec6a909202bc1b7b78"
3
+ "digest": "sha256:98116f43f35fb99d4ea06e08440b17a5bfe1705f0c35542f22ac63134763ad43"
4
4
  }