@geraldmaron/construct 1.0.6 → 1.0.7
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 +19 -17
- package/agents/contracts.json +617 -2
- package/agents/contracts.schema.json +83 -0
- package/agents/prompts/cx-accessibility.md +2 -0
- package/agents/prompts/cx-ai-engineer.md +2 -0
- package/agents/prompts/cx-architect.md +2 -0
- package/agents/prompts/cx-business-strategist.md +2 -0
- package/agents/prompts/cx-data-analyst.md +2 -0
- package/agents/prompts/cx-data-engineer.md +2 -0
- package/agents/prompts/cx-debugger.md +2 -0
- package/agents/prompts/cx-designer.md +2 -0
- package/agents/prompts/cx-devil-advocate.md +2 -0
- package/agents/prompts/cx-docs-keeper.md +2 -0
- package/agents/prompts/cx-engineer.md +2 -0
- package/agents/prompts/cx-evaluator.md +2 -0
- package/agents/prompts/cx-explorer.md +2 -0
- package/agents/prompts/cx-legal-compliance.md +2 -0
- package/agents/prompts/cx-operations.md +2 -0
- package/agents/prompts/cx-orchestrator.md +2 -0
- package/agents/prompts/cx-platform-engineer.md +2 -0
- package/agents/prompts/cx-product-manager.md +2 -0
- package/agents/prompts/cx-qa.md +2 -0
- package/agents/prompts/cx-rd-lead.md +2 -0
- package/agents/prompts/cx-release-manager.md +2 -0
- package/agents/prompts/cx-researcher.md +2 -0
- package/agents/prompts/cx-reviewer.md +2 -0
- package/agents/prompts/cx-security.md +2 -0
- package/agents/prompts/cx-sre.md +2 -0
- package/agents/prompts/cx-test-automation.md +2 -0
- package/agents/prompts/cx-trace-reviewer.md +2 -0
- package/agents/prompts/cx-ux-researcher.md +2 -0
- package/agents/registry.json +8 -3
- package/bin/construct +209 -32
- package/commands/build/feature.md +1 -1
- package/commands/build/fix.md +1 -1
- package/commands/design/access.md +1 -1
- package/commands/design/flow.md +1 -1
- package/commands/design/ui.md +1 -1
- package/commands/measure/experiment.md +1 -1
- package/commands/measure/metrics.md +1 -1
- package/commands/measure/results.md +1 -1
- package/commands/plan/api.md +1 -1
- package/commands/plan/challenge.md +1 -1
- package/commands/plan/decide.md +1 -1
- package/commands/plan/feature.md +1 -1
- package/commands/plan/requirements.md +1 -1
- package/commands/remember/context.md +1 -1
- package/commands/remember/handoff.md +1 -1
- package/commands/remember/runbook.md +1 -1
- package/commands/review/code.md +1 -1
- package/commands/review/quality.md +1 -1
- package/commands/review/security.md +1 -1
- package/commands/ship/ready.md +1 -1
- package/commands/ship/release.md +1 -1
- package/commands/ship/status.md +1 -1
- package/commands/understand/docs.md +1 -1
- package/commands/understand/this.md +1 -1
- package/commands/understand/why.md +1 -1
- package/commands/work/clean.md +1 -1
- package/commands/work/drive.md +1 -1
- package/commands/work/optimize-prompts.md +1 -1
- package/commands/work/parallel-review.md +1 -1
- package/lib/auto-docs.mjs +7 -7
- package/lib/boundary.mjs +126 -0
- package/lib/cache-strategy-google.js +26 -31
- package/lib/comment-lint.mjs +134 -0
- package/lib/contracts/validate.mjs +323 -0
- package/lib/daemons/contract.mjs +210 -0
- package/lib/docs-verify.mjs +59 -6
- package/lib/doctor/cli.mjs +16 -1
- package/lib/doctor/index.mjs +3 -1
- package/lib/doctor/watchers/consistency.mjs +310 -0
- package/lib/doctor/watchers/mcp-protocol.mjs +232 -0
- package/lib/document-extract.mjs +211 -1
- package/lib/embed/cli.mjs +124 -3
- package/lib/embed/daemon.mjs +43 -4
- package/lib/embed/docs-lifecycle.mjs +1 -1
- package/lib/embed/inbox.mjs +2 -0
- package/lib/embed/scheduler.mjs +33 -5
- package/lib/evaluator-optimizer.mjs +2 -3
- package/lib/hooks/comment-lint.mjs +16 -0
- package/lib/hooks/mcp-audit.mjs +2 -1
- package/lib/hooks/proactive-activation.mjs +0 -14
- package/lib/hooks/rule-verifier.mjs +217 -0
- package/lib/hooks/session-optimize.mjs +2 -1
- package/lib/init-unified.mjs +55 -65
- package/lib/intake/classify.mjs +108 -24
- package/lib/intake/daemon.mjs +121 -0
- package/lib/intake/filesystem-queue.mjs +6 -1
- package/lib/intake/intake-config.mjs +2 -1
- package/lib/intake/prepare.mjs +0 -1
- package/lib/intake/session-prelude.mjs +7 -1
- package/lib/intake/traceability.mjs +90 -0
- package/lib/knowledge/research-store.mjs +2 -0
- package/lib/maintenance/cleanup.mjs +315 -0
- package/lib/mcp/memory-bridge.mjs +276 -0
- package/lib/mcp/server.mjs +2 -0
- package/lib/mcp/tools/workflow.mjs +25 -0
- package/lib/mcp-catalog.json +12 -8
- package/lib/mcp-platform-config.mjs +16 -8
- package/lib/migrations/index.mjs +106 -0
- package/lib/migrations/v1-baseline.mjs +33 -0
- package/lib/observation-store.mjs +9 -4
- package/lib/outcomes/record.mjs +2 -0
- package/lib/profiles/rebrand.mjs +46 -0
- package/lib/project-init-shared.mjs +12 -0
- package/lib/provider-capabilities.js +20 -7
- package/lib/providers/auth-manager.mjs +58 -17
- package/lib/reflect.mjs +49 -12
- package/lib/server/index.mjs +22 -28
- package/lib/session-store.mjs +6 -4
- package/lib/setup.mjs +14 -3
- package/lib/telemetry/client.mjs +5 -1
- package/lib/version.mjs +51 -0
- package/lib/worker/trace.mjs +5 -1
- package/package.json +4 -1
- package/personas/construct.md +3 -1
- package/rules/common/development-workflow.md +2 -1
- package/rules/common/no-fabrication.md +69 -0
- package/rules/common/review-before-change.md +58 -0
- package/scripts/sync-agents.mjs +45 -14
- package/templates/docs/construct_guide.md +6 -6
- package/templates/docs/skill-artifact.md +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
rules/common/review-before-change.md: audit the current state before authoring anything new.
|
|
3
|
+
|
|
4
|
+
Applies to every specialist on every platform. Pairs with framing.md (frame the
|
|
5
|
+
problem) and development-workflow.md step 0 (research and reuse before code).
|
|
6
|
+
This rule extends the same discipline to artifacts: docs, strategy, PRDs, ADRs,
|
|
7
|
+
RFCs, rules, templates, and any other durable file. Read before scaffolding.
|
|
8
|
+
-->
|
|
9
|
+
# Review Before Change
|
|
10
|
+
|
|
11
|
+
Before creating or rewriting a durable artifact, check what already exists.
|
|
12
|
+
|
|
13
|
+
This rule exists because the most common waste in Construct is duplicated effort: a new strategy doc landing next to a PRD that already covers it, a new rule re-stating a section of `framing.md`, a new diagram drawn while an equivalent one sits two folders away. The fix is not more process. It is a fifteen-second audit before the first write.
|
|
14
|
+
|
|
15
|
+
## When this applies
|
|
16
|
+
|
|
17
|
+
Any time the work would produce or significantly rewrite one of:
|
|
18
|
+
|
|
19
|
+
- A doc under `docs/`, including concepts, cookbook, providers, runbooks, ADRs, RFCs, PRDs, memos, runbooks, decisions.
|
|
20
|
+
- A rule under `rules/` or a skill under `skills/`.
|
|
21
|
+
- A template under `templates/`.
|
|
22
|
+
- A top-level repo doc (README, CHANGELOG, STRATEGY, AGENTS, CONTRIBUTING).
|
|
23
|
+
- A profile under `profiles/` or a registered agent.
|
|
24
|
+
|
|
25
|
+
It does not apply to local-only working files (`plan.md`, `.cx/` state, draft scratch).
|
|
26
|
+
|
|
27
|
+
## The audit
|
|
28
|
+
|
|
29
|
+
Before writing, answer all three:
|
|
30
|
+
|
|
31
|
+
1. **Does an artifact for this already exist?** Search by topic, not filename. `grep -rli "<topic>" docs/ rules/ skills/` is the floor. If something close exists, the default is to extend or supersede, not to create a sibling.
|
|
32
|
+
2. **Is there a template or canonical shape for this artifact type?** Check `templates/docs/` and the matching `skills/docs/*-workflow.md`. If a shape exists, use it; do not invent a new structure.
|
|
33
|
+
3. **What is the canonical home for this kind of content?** A strategy doc belongs in one place. A new ADR does not live in `docs/notes/`. If you have to think about where to put it, the location is wrong.
|
|
34
|
+
|
|
35
|
+
If any answer surfaces an existing artifact, you have two valid moves:
|
|
36
|
+
|
|
37
|
+
- **Extend it.** Add the missing section to the existing file.
|
|
38
|
+
- **Supersede it.** Replace the old artifact and mark it superseded. Do not leave two competing sources of truth.
|
|
39
|
+
|
|
40
|
+
Creating a new sibling artifact "because the old one didn't quite fit" is the failure mode this rule prevents. If the old one doesn't fit, fix it.
|
|
41
|
+
|
|
42
|
+
## Documenting the audit
|
|
43
|
+
|
|
44
|
+
For artifacts that go through a review cycle (strategy, PRD, ADR, RFC), the framing or problem-statement section should briefly note what existing artifacts were reviewed and why a new one is warranted. One sentence is enough. The point is to leave evidence that the audit happened.
|
|
45
|
+
|
|
46
|
+
## Anti-patterns
|
|
47
|
+
|
|
48
|
+
- Creating `docs/notes/strategy.md` because you didn't notice `STRATEGY.md` at the root.
|
|
49
|
+
- Writing a new rule that paraphrases an existing one.
|
|
50
|
+
- Adding a new template alongside `templates/docs/strategy.md` because the existing one "needed a couple of tweaks."
|
|
51
|
+
- Drafting an ADR for a decision already captured in an existing ADR.
|
|
52
|
+
- Producing a recipe in `docs/cookbook/` for a workflow already documented in `docs/concepts/`.
|
|
53
|
+
|
|
54
|
+
## Related
|
|
55
|
+
|
|
56
|
+
- `rules/common/framing.md`: frame the underlying problem before reaching for inputs.
|
|
57
|
+
- `rules/common/development-workflow.md`: step 0 covers the same discipline for code.
|
|
58
|
+
- `rules/common/doc-ownership.md`: which specialist owns which artifact type.
|
package/scripts/sync-agents.mjs
CHANGED
|
@@ -121,6 +121,18 @@ if (validationErrors.length > 0) {
|
|
|
121
121
|
process.exit(1);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
// Sync-time contract validation: contracts.json shape, schema refs, and
|
|
125
|
+
// producer/consumer name resolution against the registry above.
|
|
126
|
+
{
|
|
127
|
+
const { validateContractsFile } = await import("../lib/contracts/validate.mjs");
|
|
128
|
+
const contractsResult = validateContractsFile();
|
|
129
|
+
if (!contractsResult.ok) {
|
|
130
|
+
console.error("Contract validation failed:");
|
|
131
|
+
for (const err of contractsResult.errors) console.error(` - ${err}`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
124
136
|
// --- Dry-run + lockfile + two-phase write infrastructure ---
|
|
125
137
|
|
|
126
138
|
const DRY_RUN = process.argv.includes("--dry-run");
|
|
@@ -671,9 +683,13 @@ ${agentList || "(all specialists are internal — routed through Construct)"}`;
|
|
|
671
683
|
if (!settings.mcpServers) settings.mcpServers = {};
|
|
672
684
|
const registryMcp = registry.mcpServers ?? {};
|
|
673
685
|
for (const [id, mcpDef] of Object.entries(registryMcp)) {
|
|
674
|
-
const
|
|
686
|
+
const existingEntry = settings.mcpServers[id];
|
|
687
|
+
const existing = JSON.stringify(existingEntry ?? "");
|
|
675
688
|
const hasPlaceholder = existing.includes("__");
|
|
676
|
-
|
|
689
|
+
const registryWantsCommand = !mcpDef.type && Array.isArray(mcpDef.args);
|
|
690
|
+
const existingIsRemote = existingEntry && (existingEntry.type === 'http' || existingEntry.type === 'remote');
|
|
691
|
+
const transportMismatch = registryWantsCommand && existingIsRemote;
|
|
692
|
+
if (existingEntry && !hasPlaceholder && !transportMismatch) continue;
|
|
677
693
|
settings.mcpServers[id] = buildClaudeMcpEntry(id, mcpDef, process.env);
|
|
678
694
|
}
|
|
679
695
|
if (!DRY_RUN) fs.writeFileSync(claudeSettingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
@@ -711,8 +727,8 @@ function hasCodexMcpTable(text, id) {
|
|
|
711
727
|
return new RegExp(`^\\[mcp_servers\\.(?:${escapeRegExp(id)}|${escapeRegExp(tomlString(id))})\\]`, "m").test(text);
|
|
712
728
|
}
|
|
713
729
|
|
|
714
|
-
function isCodexMcpSupported(
|
|
715
|
-
return
|
|
730
|
+
function isCodexMcpSupported() {
|
|
731
|
+
return true;
|
|
716
732
|
}
|
|
717
733
|
|
|
718
734
|
function syncCodex(entries) {
|
|
@@ -834,9 +850,13 @@ function syncVSCode() {
|
|
|
834
850
|
if (!settings["github.copilot.mcpServers"]) settings["github.copilot.mcpServers"] = {};
|
|
835
851
|
const mcpServers = settings["github.copilot.mcpServers"];
|
|
836
852
|
for (const [id, mcpDef] of Object.entries(registryMcp)) {
|
|
837
|
-
const
|
|
853
|
+
const existingEntry = mcpServers[id];
|
|
854
|
+
const existing = JSON.stringify(existingEntry ?? "");
|
|
838
855
|
const hasPlaceholder = existing.includes("__");
|
|
839
|
-
|
|
856
|
+
const registryWantsCommand = !mcpDef.type && Array.isArray(mcpDef.args);
|
|
857
|
+
const existingIsRemote = existingEntry && (existingEntry.type === 'http' || existingEntry.type === 'remote');
|
|
858
|
+
const transportMismatch = registryWantsCommand && existingIsRemote;
|
|
859
|
+
if (existingEntry && !hasPlaceholder && !transportMismatch) continue;
|
|
840
860
|
mcpServers[id] = buildClaudeMcpEntry(id, mcpDef, process.env);
|
|
841
861
|
}
|
|
842
862
|
settings["github.copilot.mcpServers"] = mcpServers;
|
|
@@ -862,9 +882,13 @@ function syncCursor() {
|
|
|
862
882
|
const config = JSON.parse(fs.readFileSync(cursorMcpPath, "utf8"));
|
|
863
883
|
if (!config.mcpServers) config.mcpServers = {};
|
|
864
884
|
for (const [id, mcpDef] of Object.entries(registryMcp)) {
|
|
865
|
-
const
|
|
885
|
+
const existingEntry = config.mcpServers[id];
|
|
886
|
+
const existing = JSON.stringify(existingEntry ?? "");
|
|
866
887
|
const hasPlaceholder = existing.includes("__");
|
|
867
|
-
|
|
888
|
+
const registryWantsCommand = !mcpDef.type && Array.isArray(mcpDef.args);
|
|
889
|
+
const existingIsRemote = existingEntry && (existingEntry.type === 'http' || existingEntry.type === 'remote');
|
|
890
|
+
const transportMismatch = registryWantsCommand && existingIsRemote;
|
|
891
|
+
if (existingEntry && !hasPlaceholder && !transportMismatch) continue;
|
|
868
892
|
config.mcpServers[id] = buildClaudeMcpEntry(id, mcpDef, process.env);
|
|
869
893
|
}
|
|
870
894
|
if (!DRY_RUN) fs.writeFileSync(cursorMcpPath, JSON.stringify(config, null, 2) + "\n");
|
|
@@ -963,14 +987,21 @@ function syncOpencode(entries) {
|
|
|
963
987
|
for (const [id, mcpDef] of Object.entries(registryMcp)) {
|
|
964
988
|
const openCodeId = getOpenCodeMcpId(id);
|
|
965
989
|
if (openCodeId !== id) delete config.mcp[id];
|
|
966
|
-
if (id === 'memory' && config.mcp.cass && !config.mcp[openCodeId]) {
|
|
967
|
-
config.mcp[openCodeId] = config.mcp.cass;
|
|
968
|
-
}
|
|
969
990
|
if (id === 'memory') delete config.mcp.cass;
|
|
970
|
-
|
|
971
|
-
|
|
991
|
+
|
|
992
|
+
// Migrate the legacy cass-memory HTTP entry to the stdio bridge. cm v0.2.x
|
|
993
|
+
// rejects the MCP handshake (OpenCode surfaces 405 on the SSE GET), so
|
|
994
|
+
// any remote/http memory entry must be rewritten when the registry
|
|
995
|
+
// defines a command-based bridge.
|
|
996
|
+
const existingEntry = config.mcp[openCodeId];
|
|
997
|
+
const registryWantsCommand = !mcpDef.type && Array.isArray(mcpDef.args);
|
|
998
|
+
const existingIsRemote = existingEntry && (existingEntry.type === 'remote' || existingEntry.type === 'http');
|
|
999
|
+
const transportMismatch = registryWantsCommand && existingIsRemote;
|
|
1000
|
+
|
|
1001
|
+
const existing = JSON.stringify(existingEntry ?? "");
|
|
1002
|
+
const hasPlaceholder = existing.includes("__");
|
|
972
1003
|
const argsHaveTemplates = (mcpDef.args ?? []).some((a) => typeof a === 'string' && a.includes('__'));
|
|
973
|
-
if (!
|
|
1004
|
+
if (!existingEntry || hasPlaceholder || argsHaveTemplates || transportMismatch) {
|
|
974
1005
|
config.mcp[openCodeId] = buildOpenCodeMcpEntry(id, mcpDef, process.env).entry;
|
|
975
1006
|
}
|
|
976
1007
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated by `construct init` to help you get oriented. It's safe to edit: Construct only writes it once, then leaves it alone.
|
|
4
4
|
|
|
5
|
-
**Full docs:** [https://geraldmaron.github.io/construct/
|
|
5
|
+
**Full docs:** [https://geraldmaron.github.io/construct/](https://geraldmaron.github.io/construct/)
|
|
6
6
|
|
|
7
7
|
## What Construct is doing in your project
|
|
8
8
|
|
|
@@ -117,7 +117,7 @@ All ports bind to `127.0.0.1` only; nothing is reachable from other machines on
|
|
|
117
117
|
| `construct search "..."` | Hybrid file + SQL + semantic search over project state |
|
|
118
118
|
| `construct uninstall` | Interactive teardown: never touches Docker or your code |
|
|
119
119
|
|
|
120
|
-
Full reference: <https://geraldmaron.github.io/construct/
|
|
120
|
+
Full reference: <https://geraldmaron.github.io/construct/docs/reference/cli>
|
|
121
121
|
|
|
122
122
|
## Updating Construct
|
|
123
123
|
|
|
@@ -134,13 +134,13 @@ construct doctor # most issues surface here with a fix hint
|
|
|
134
134
|
construct down && construct up # restart local services
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
Troubleshooting guide: <https://geraldmaron.github.io/construct/
|
|
137
|
+
Troubleshooting guide: <https://geraldmaron.github.io/construct/docs/operations/troubleshooting>
|
|
138
138
|
|
|
139
139
|
## Next steps
|
|
140
140
|
|
|
141
|
-
- [Connect your editor](https://geraldmaron.github.io/construct/
|
|
142
|
-
- [Run your first task](https://geraldmaron.github.io/construct/
|
|
143
|
-
- Skim [the architecture](https://geraldmaron.github.io/construct/
|
|
141
|
+
- [Connect your editor](https://geraldmaron.github.io/construct/docs/start/connect-your-editor) if you haven't already.
|
|
142
|
+
- [Run your first task](https://geraldmaron.github.io/construct/docs/start/first-task) to feel the flow.
|
|
143
|
+
- Skim [the architecture](https://geraldmaron.github.io/construct/docs/concepts/architecture) when you have 10 minutes: it'll save you hours later.
|
|
144
144
|
|
|
145
145
|
If you'd rather have a teammate walk you through it, the persona itself can:
|
|
146
146
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: <verb-led-id>
|
|
3
|
-
scope: <one paragraph: what it covers, what it does not>
|
|
3
|
+
scope: "<one paragraph: what it covers, what it does not>"
|
|
4
4
|
observable_outcome: <how someone outside the role tells this skill happened>
|
|
5
5
|
provenance:
|
|
6
6
|
- <citation: post-mortem, public framework, competency model>
|