@topogram/cli 0.3.62 → 0.3.64
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/package.json +1 -1
- package/src/adoption/plan.d.ts +6 -0
- package/src/adoption/reporting.d.ts +10 -0
- package/src/adoption/review-groups.d.ts +6 -0
- package/src/agent-brief.d.ts +3 -0
- package/src/agent-brief.js +495 -0
- package/src/agent-ops/query-builders.d.ts +26 -0
- package/src/archive/archive.d.ts +2 -0
- package/src/archive/compact.d.ts +1 -0
- package/src/archive/unarchive.d.ts +1 -0
- package/src/catalog.d.ts +10 -0
- package/src/catalog.js +62 -66
- package/src/cli/catalog-alias.d.ts +1 -0
- package/src/cli/command-parser.js +38 -0
- package/src/cli/command-parsers/core.js +102 -0
- package/src/cli/command-parsers/generator.js +39 -0
- package/src/cli/command-parsers/import.js +44 -0
- package/src/cli/command-parsers/legacy-workflow.js +21 -0
- package/src/cli/command-parsers/project.js +47 -0
- package/src/cli/command-parsers/sdlc.js +47 -0
- package/src/cli/command-parsers/shared.js +51 -0
- package/src/cli/command-parsers/template.js +48 -0
- package/src/cli/commands/agent.js +47 -0
- package/src/cli/commands/catalog.js +617 -0
- package/src/cli/commands/check.js +268 -0
- package/src/cli/commands/doctor.js +268 -0
- package/src/cli/commands/emit.js +149 -0
- package/src/cli/commands/generate.js +96 -0
- package/src/cli/commands/generator-policy.js +785 -0
- package/src/cli/commands/generator.js +443 -0
- package/src/cli/commands/import-runner.js +157 -0
- package/src/cli/commands/import.js +1734 -0
- package/src/cli/commands/inspect.js +55 -0
- package/src/cli/commands/new.js +94 -0
- package/src/cli/commands/package.js +815 -0
- package/src/cli/commands/query.js +1302 -0
- package/src/cli/commands/release-rollout.js +257 -0
- package/src/cli/commands/release-shared.js +528 -0
- package/src/cli/commands/release-status.js +429 -0
- package/src/cli/commands/release.js +107 -0
- package/src/cli/commands/sdlc.js +168 -0
- package/src/cli/commands/setup.js +76 -0
- package/src/cli/commands/source.js +291 -0
- package/src/cli/commands/template-runner.js +198 -0
- package/src/cli/commands/template.js +2145 -0
- package/src/cli/commands/trust.js +219 -0
- package/src/cli/commands/version.js +40 -0
- package/src/cli/commands/widget.js +168 -0
- package/src/cli/commands/workflow.js +63 -0
- package/src/cli/dispatcher.js +392 -0
- package/src/cli/help-dispatch.js +188 -0
- package/src/cli/help.js +296 -0
- package/src/cli/migration-guidance.js +59 -0
- package/src/cli/options.js +96 -0
- package/src/cli/output-safety.js +107 -0
- package/src/cli/path-normalization.js +29 -0
- package/src/cli.js +47 -11711
- package/src/example-implementation.d.ts +2 -0
- package/src/format.d.ts +1 -0
- package/src/generator/check.d.ts +1 -0
- package/src/generator/context/bundle.d.ts +1 -0
- package/src/generator/context/shared.d.ts +2 -0
- package/src/generator/native/parity-bundle.js +2 -1
- package/src/generator/surfaces/web/html-escape.js +22 -0
- package/src/generator/surfaces/web/react.js +10 -8
- package/src/generator/surfaces/web/sveltekit.js +7 -5
- package/src/generator/surfaces/web/vanilla.js +8 -4
- package/src/generator.d.ts +2 -0
- package/src/github-client.js +520 -0
- package/src/import/core/shared.js +20 -62
- package/src/import/extractors/api/flutter-dio.js +4 -8
- package/src/import/extractors/api/react-native-repository.js +4 -8
- package/src/import/index.d.ts +4 -0
- package/src/import/provenance.d.ts +4 -0
- package/src/new-project.js +100 -11
- package/src/npm-safety.js +79 -0
- package/src/parser.d.ts +1 -0
- package/src/path-helpers.d.ts +1 -0
- package/src/path-helpers.js +20 -0
- package/src/project-config.js +1 -0
- package/src/reconcile/docs.d.ts +8 -0
- package/src/reconcile/journeys.d.ts +1 -0
- package/src/resolver.d.ts +1 -0
- package/src/runtime-support.js +29 -0
- package/src/sdlc/adopt.d.ts +1 -0
- package/src/sdlc/check.d.ts +1 -0
- package/src/sdlc/explain.d.ts +1 -0
- package/src/sdlc/release.d.ts +1 -0
- package/src/sdlc/scaffold.d.ts +1 -0
- package/src/sdlc/transition.d.ts +1 -0
- package/src/text-helpers.d.ts +6 -0
- package/src/text-helpers.js +245 -0
- package/src/topogram-config.js +306 -0
- package/src/validator.d.ts +2 -0
- package/src/workflows/adoption/index.js +26 -0
- package/src/workflows/docs-generate.js +262 -0
- package/src/workflows/docs-scan.js +703 -0
- package/src/workflows/docs.js +15 -0
- package/src/workflows/import-app/api.js +799 -0
- package/src/workflows/import-app/db.js +538 -0
- package/src/workflows/import-app/index.js +30 -0
- package/src/workflows/import-app/shared.js +218 -0
- package/src/workflows/import-app/ui.js +443 -0
- package/src/workflows/import-app/workflow.js +159 -0
- package/src/workflows/reconcile/adoption-plan.js +742 -0
- package/src/workflows/reconcile/auth.js +692 -0
- package/src/workflows/reconcile/bundle-core.js +600 -0
- package/src/workflows/reconcile/bundle-shared.js +75 -0
- package/src/workflows/reconcile/candidate-model.js +477 -0
- package/src/workflows/reconcile/canonical-surface.js +264 -0
- package/src/workflows/reconcile/gap-report.js +333 -0
- package/src/workflows/reconcile/ids.js +6 -0
- package/src/workflows/reconcile/impacts.js +625 -0
- package/src/workflows/reconcile/index.js +7 -0
- package/src/workflows/reconcile/renderers.js +461 -0
- package/src/workflows/reconcile/summary.js +90 -0
- package/src/workflows/reconcile/workflow.js +309 -0
- package/src/workflows/shared.js +189 -0
- package/src/workflows/types.d.ts +93 -0
- package/src/workflows.d.ts +1 -0
- package/src/workflows.js +10 -7652
package/package.json
CHANGED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function adoptionItemKey(...args: any[]): string;
|
|
2
|
+
export function applyAdoptionSelector(...args: any[]): any;
|
|
3
|
+
export function buildAgentAdoptionPlan(...args: any[]): any;
|
|
4
|
+
export function mergeAdoptionPlanState(...args: any[]): any[];
|
|
5
|
+
export function parseAdoptSelector(...args: any[]): any;
|
|
6
|
+
export function summarizeAdoptionPlanItems(...args: any[]): any;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function attachBundleOperatorHints(...args: any[]): any;
|
|
2
|
+
export function annotateBundlePriorities(...args: any[]): any;
|
|
3
|
+
export function buildAdoptionStatusFiles(...args: any[]): any;
|
|
4
|
+
export function buildAdoptionStatusSummary(...args: any[]): any;
|
|
5
|
+
export function buildPromotedCanonicalItems(...args: any[]): any;
|
|
6
|
+
export function renderBundlePriorityActionsMarkdown(...args: any[]): string;
|
|
7
|
+
export function renderNextBestActionMarkdown(...args: any[]): string;
|
|
8
|
+
export function renderPreviewFollowupMarkdown(...args: any[]): string;
|
|
9
|
+
export function renderPreviewRiskMarkdown(...args: any[]): string;
|
|
10
|
+
export function renderPromotedCanonicalItemsMarkdown(...args: any[]): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function buildBundleAdoptionPriorities(...args: any[]): any[];
|
|
2
|
+
export function buildBundleBlockerSummaries(...args: any[]): any[];
|
|
3
|
+
export function buildProjectionReviewGroups(...args: any[]): any[];
|
|
4
|
+
export function buildUiReviewGroups(...args: any[]): any[];
|
|
5
|
+
export function buildWorkflowReviewGroups(...args: any[]): any[];
|
|
6
|
+
export function selectNextBundle(...args: any[]): any;
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
GENERATOR_POLICY_FILE,
|
|
8
|
+
generatorPolicyDiagnosticsForBindings,
|
|
9
|
+
loadGeneratorPolicy,
|
|
10
|
+
packageBackedGeneratorBindings
|
|
11
|
+
} from "./generator-policy.js";
|
|
12
|
+
import { TOPOGRAM_IMPORT_FILE } from "./import/provenance.js";
|
|
13
|
+
import {
|
|
14
|
+
loadProjectConfig,
|
|
15
|
+
projectConfigOrDefault,
|
|
16
|
+
validateProjectConfig
|
|
17
|
+
} from "./project-config.js";
|
|
18
|
+
import { resolveWorkspace } from "./resolver.js";
|
|
19
|
+
import {
|
|
20
|
+
getTemplateTrustStatus,
|
|
21
|
+
TEMPLATE_TRUST_FILE
|
|
22
|
+
} from "./template-trust.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {{ path: string, reason: string, required: boolean, exists: boolean }} AgentBriefReadItem
|
|
26
|
+
* @typedef {{ command: string, reason: string, phase: string }} AgentBriefCommand
|
|
27
|
+
* @typedef {{ path: string, ownership: string, rule: string }} AgentBriefOutputBoundary
|
|
28
|
+
* @typedef {{ id: string, title: string, commands: string[], rule: string }} AgentBriefWorkflow
|
|
29
|
+
* @typedef {{ id: string, kind: string, projection: string|null, generator: string|null, uses_api: string|null, uses_database: string|null }} AgentBriefRuntime
|
|
30
|
+
* @typedef {{ path: string, source: string|null, tracks: string[], candidateCounts: Record<string, any>, ownership: string|null }} AgentBriefImport
|
|
31
|
+
* @typedef {{ ok: true, payload: Record<string, any> } | { ok: false, kind: "topogram", validation: any } | { ok: false, kind: "project", validation: any, configPath: string }} AgentBriefResult
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} inputPath
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeAgentTopogramPath(inputPath) {
|
|
39
|
+
const resolved = path.resolve(inputPath || "./topogram");
|
|
40
|
+
if (path.basename(resolved) === "topogram") {
|
|
41
|
+
return resolved;
|
|
42
|
+
}
|
|
43
|
+
const nested = path.join(resolved, "topogram");
|
|
44
|
+
return fs.existsSync(nested) && fs.statSync(nested).isDirectory() ? nested : resolved;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {string} inputPath
|
|
49
|
+
* @returns {string}
|
|
50
|
+
*/
|
|
51
|
+
function normalizeProjectRoot(inputPath) {
|
|
52
|
+
const resolved = path.resolve(inputPath || ".");
|
|
53
|
+
if (path.basename(resolved) === "topogram") {
|
|
54
|
+
return path.dirname(resolved);
|
|
55
|
+
}
|
|
56
|
+
if (fs.existsSync(path.join(resolved, "topogram.project.json"))) {
|
|
57
|
+
return resolved;
|
|
58
|
+
}
|
|
59
|
+
if (fs.existsSync(path.join(resolved, "topogram"))) {
|
|
60
|
+
return resolved;
|
|
61
|
+
}
|
|
62
|
+
return path.dirname(normalizeAgentTopogramPath(inputPath));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param {string} projectRoot
|
|
67
|
+
* @param {string} targetPath
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
function relativeProjectPath(projectRoot, targetPath) {
|
|
71
|
+
const relative = path.relative(projectRoot, targetPath);
|
|
72
|
+
if (!relative || relative === "") {
|
|
73
|
+
return ".";
|
|
74
|
+
}
|
|
75
|
+
return relative.split(path.sep).join("/");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {string} projectRoot
|
|
80
|
+
* @param {string} relativePath
|
|
81
|
+
* @param {string} reason
|
|
82
|
+
* @param {boolean} required
|
|
83
|
+
* @returns {AgentBriefReadItem}
|
|
84
|
+
*/
|
|
85
|
+
function readItem(projectRoot, relativePath, reason, required) {
|
|
86
|
+
return {
|
|
87
|
+
path: relativePath,
|
|
88
|
+
reason,
|
|
89
|
+
required,
|
|
90
|
+
exists: fs.existsSync(path.join(projectRoot, relativePath))
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param {string} command
|
|
96
|
+
* @param {string} reason
|
|
97
|
+
* @param {string} [phase]
|
|
98
|
+
* @returns {AgentBriefCommand}
|
|
99
|
+
*/
|
|
100
|
+
function commandItem(command, reason, phase = "first-run") {
|
|
101
|
+
return { command, reason, phase };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {Record<string, any>} config
|
|
106
|
+
* @returns {AgentBriefRuntime[]}
|
|
107
|
+
*/
|
|
108
|
+
function summarizeRuntimes(config) {
|
|
109
|
+
const runtimes = Array.isArray(config?.topology?.runtimes) ? config.topology.runtimes : [];
|
|
110
|
+
return runtimes.map((runtime) => ({
|
|
111
|
+
id: String(runtime.id || "unknown"),
|
|
112
|
+
kind: String(runtime.kind || "unknown"),
|
|
113
|
+
projection: typeof runtime.projection === "string" ? runtime.projection : null,
|
|
114
|
+
generator: typeof runtime.generator?.id === "string" ? runtime.generator.id : null,
|
|
115
|
+
uses_api: typeof runtime.uses_api === "string" ? runtime.uses_api : null,
|
|
116
|
+
uses_database: typeof runtime.uses_database === "string" ? runtime.uses_database : null
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {Record<string, any>} config
|
|
122
|
+
* @returns {AgentBriefOutputBoundary[]}
|
|
123
|
+
*/
|
|
124
|
+
function summarizeOutputBoundaries(config) {
|
|
125
|
+
const outputs = config?.outputs && typeof config.outputs === "object" && !Array.isArray(config.outputs)
|
|
126
|
+
? config.outputs
|
|
127
|
+
: {};
|
|
128
|
+
return Object.entries(outputs).map(([name, output]) => {
|
|
129
|
+
const ownership = String(output?.ownership || "unknown");
|
|
130
|
+
const outputPath = String(output?.path || name);
|
|
131
|
+
return {
|
|
132
|
+
path: outputPath,
|
|
133
|
+
ownership,
|
|
134
|
+
rule: ownership === "generated"
|
|
135
|
+
? `Do not edit ${outputPath}/ directly unless changing output ownership to maintained. Regenerate it from the Topogram.`
|
|
136
|
+
: `Maintained output ${outputPath}/ is project-owned; agents may edit it directly after reading the relevant Topogram packets.`
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {string} projectRoot
|
|
143
|
+
* @returns {AgentBriefImport|null}
|
|
144
|
+
*/
|
|
145
|
+
function readImportSummary(projectRoot) {
|
|
146
|
+
const importPath = path.join(projectRoot, TOPOGRAM_IMPORT_FILE);
|
|
147
|
+
if (!fs.existsSync(importPath)) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const record = JSON.parse(fs.readFileSync(importPath, "utf8"));
|
|
152
|
+
return {
|
|
153
|
+
path: TOPOGRAM_IMPORT_FILE,
|
|
154
|
+
source: typeof record?.source?.path === "string" ? record.source.path : null,
|
|
155
|
+
tracks: Array.isArray(record?.import?.tracks) ? record.import.tracks.map(String) : [],
|
|
156
|
+
candidateCounts: record?.import?.candidateCounts && typeof record.import.candidateCounts === "object"
|
|
157
|
+
? record.import.candidateCounts
|
|
158
|
+
: {},
|
|
159
|
+
ownership: typeof record?.ownership?.importedArtifacts === "string" ? record.ownership.importedArtifacts : null
|
|
160
|
+
};
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return {
|
|
163
|
+
path: TOPOGRAM_IMPORT_FILE,
|
|
164
|
+
source: null,
|
|
165
|
+
tracks: [],
|
|
166
|
+
candidateCounts: {},
|
|
167
|
+
ownership: `invalid: ${error instanceof Error ? error.message : String(error)}`
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {Record<string, any>} config
|
|
174
|
+
* @param {boolean} hasImportRecord
|
|
175
|
+
* @returns {AgentBriefWorkflow[]}
|
|
176
|
+
*/
|
|
177
|
+
function buildWorkflows(config, hasImportRecord) {
|
|
178
|
+
const workflows = [
|
|
179
|
+
{
|
|
180
|
+
id: "greenfield-generated",
|
|
181
|
+
title: "Generated project loop",
|
|
182
|
+
commands: [
|
|
183
|
+
"npm run agent:brief",
|
|
184
|
+
"npm run check",
|
|
185
|
+
"npm run generate",
|
|
186
|
+
"npm run verify"
|
|
187
|
+
],
|
|
188
|
+
rule: "Edit the Topogram first, then regenerate generated-owned outputs."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "widget-first-ui",
|
|
192
|
+
title: "Widget-first UI loop",
|
|
193
|
+
commands: [
|
|
194
|
+
"topogram query list --json",
|
|
195
|
+
"topogram query show widget-behavior",
|
|
196
|
+
"topogram widget check --json",
|
|
197
|
+
"topogram widget behavior --json",
|
|
198
|
+
"topogram emit ui-widget-contract --json"
|
|
199
|
+
],
|
|
200
|
+
rule: "Use focused widget and surface packets before editing UI code."
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: "template-update",
|
|
204
|
+
title: "Template update loop",
|
|
205
|
+
commands: [
|
|
206
|
+
"npm run source:status",
|
|
207
|
+
"npm run template:explain",
|
|
208
|
+
"npm run template:update:recommend",
|
|
209
|
+
"npm run template:update:check"
|
|
210
|
+
],
|
|
211
|
+
rule: "Local Topogram files are project-owned after edits; review update plans before applying template changes."
|
|
212
|
+
}
|
|
213
|
+
];
|
|
214
|
+
if (config?.implementation) {
|
|
215
|
+
workflows.push({
|
|
216
|
+
id: "executable-template",
|
|
217
|
+
title: "Executable template review loop",
|
|
218
|
+
commands: [
|
|
219
|
+
"npm run trust:status",
|
|
220
|
+
"npm run trust:diff",
|
|
221
|
+
"npm run template:policy:explain",
|
|
222
|
+
"topogram trust template"
|
|
223
|
+
],
|
|
224
|
+
rule: "Review implementation code before refreshing trust. The brief does not execute implementation providers."
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (hasImportRecord) {
|
|
228
|
+
workflows.push({
|
|
229
|
+
id: "brownfield-import",
|
|
230
|
+
title: "Brownfield import adoption loop",
|
|
231
|
+
commands: [
|
|
232
|
+
"topogram import check .",
|
|
233
|
+
"topogram import plan .",
|
|
234
|
+
"topogram import adopt --list .",
|
|
235
|
+
"topogram import status .",
|
|
236
|
+
"topogram import history . --verify"
|
|
237
|
+
],
|
|
238
|
+
rule: "Imported Topogram files are editable after adoption; source hashes record trusted import evidence."
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return workflows;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @param {string} projectRoot
|
|
246
|
+
* @param {Record<string, any>} config
|
|
247
|
+
* @param {Record<string, any>} trust
|
|
248
|
+
* @param {Record<string, any>|null} importSummary
|
|
249
|
+
* @param {Record<string, any>} generatorPolicy
|
|
250
|
+
* @returns {string[]}
|
|
251
|
+
*/
|
|
252
|
+
function buildWarnings(projectRoot, config, trust, importSummary, generatorPolicy) {
|
|
253
|
+
/** @type {string[]} */
|
|
254
|
+
const warnings = [];
|
|
255
|
+
if (config?.implementation) {
|
|
256
|
+
warnings.push("implementation/ exists. Review executable implementation code before generation and before refreshing trust.");
|
|
257
|
+
}
|
|
258
|
+
if (trust?.requiresTrust && !trust?.ok) {
|
|
259
|
+
warnings.push(`${TEMPLATE_TRUST_FILE} does not currently match implementation/. Run trust status/diff and review code before trusting.`);
|
|
260
|
+
}
|
|
261
|
+
if (generatorPolicy?.diagnostics?.errors > 0) {
|
|
262
|
+
warnings.push(`${GENERATOR_POLICY_FILE} has generator policy errors. Fix policy before generating.`);
|
|
263
|
+
}
|
|
264
|
+
if (summarizeOutputBoundaries(config).some((output) => output.ownership === "generated")) {
|
|
265
|
+
warnings.push("Generated-owned outputs are replaceable by Topogram; do not make lasting edits under generated output paths.");
|
|
266
|
+
}
|
|
267
|
+
if (importSummary) {
|
|
268
|
+
warnings.push(`${TOPOGRAM_IMPORT_FILE} is present. Treat imported Topogram artifacts as project-owned after adoption; hashes are import evidence.`);
|
|
269
|
+
}
|
|
270
|
+
if (!fs.existsSync(path.join(projectRoot, "AGENTS.md"))) {
|
|
271
|
+
warnings.push("AGENTS.md is missing. Use this command as the current agent guidance source.");
|
|
272
|
+
}
|
|
273
|
+
return warnings;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {string} inputPath
|
|
278
|
+
* @param {Record<string, any>} workspaceAst
|
|
279
|
+
* @returns {AgentBriefResult}
|
|
280
|
+
*/
|
|
281
|
+
export function buildAgentBrief(inputPath, workspaceAst) {
|
|
282
|
+
const topogramRoot = normalizeAgentTopogramPath(inputPath);
|
|
283
|
+
const projectRoot = normalizeProjectRoot(inputPath);
|
|
284
|
+
const resolved = resolveWorkspace(workspaceAst);
|
|
285
|
+
if (!resolved.ok) {
|
|
286
|
+
return { ok: false, kind: "topogram", validation: resolved.validation };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const explicitProjectConfig = loadProjectConfig(projectRoot) || loadProjectConfig(topogramRoot) || loadProjectConfig(inputPath);
|
|
290
|
+
const projectConfigInfo = explicitProjectConfig || projectConfigOrDefault(projectRoot, resolved.graph, null);
|
|
291
|
+
const projectConfigValidation = projectConfigInfo
|
|
292
|
+
? validateProjectConfig(projectConfigInfo.config, resolved.graph, { configDir: projectConfigInfo.configDir })
|
|
293
|
+
: { ok: true, errors: [] };
|
|
294
|
+
if (!projectConfigValidation.ok) {
|
|
295
|
+
return {
|
|
296
|
+
ok: false,
|
|
297
|
+
kind: "project",
|
|
298
|
+
validation: projectConfigValidation,
|
|
299
|
+
configPath: projectConfigInfo?.configPath || "topogram.project.json"
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const config = projectConfigInfo?.config || {};
|
|
304
|
+
const configDir = projectConfigInfo?.configDir || projectRoot;
|
|
305
|
+
const template = config.template || {};
|
|
306
|
+
const trust = config.implementation
|
|
307
|
+
? getTemplateTrustStatus({
|
|
308
|
+
config: config.implementation,
|
|
309
|
+
configPath: projectConfigInfo?.configPath || path.join(configDir, "topogram.project.json"),
|
|
310
|
+
configDir
|
|
311
|
+
}, config)
|
|
312
|
+
: {
|
|
313
|
+
ok: true,
|
|
314
|
+
requiresTrust: false,
|
|
315
|
+
trustPath: path.join(configDir, TEMPLATE_TRUST_FILE),
|
|
316
|
+
trustRecord: null,
|
|
317
|
+
template: null,
|
|
318
|
+
implementation: null,
|
|
319
|
+
content: null,
|
|
320
|
+
issues: []
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const generatorPolicyInfo = loadGeneratorPolicy(configDir);
|
|
324
|
+
const generatorBindings = packageBackedGeneratorBindings(config);
|
|
325
|
+
const generatorDiagnostics = generatorPolicyDiagnosticsForBindings(generatorPolicyInfo, generatorBindings, "agent-brief");
|
|
326
|
+
const importSummary = readImportSummary(configDir);
|
|
327
|
+
|
|
328
|
+
const topogramReadPath = path.resolve(topogramRoot) === path.resolve(projectRoot) ? "." : "topogram/";
|
|
329
|
+
const readOrder = [
|
|
330
|
+
readItem(projectRoot, "AGENTS.md", "Human-readable first-run guidance generated with this project.", false),
|
|
331
|
+
readItem(projectRoot, "README.md", "Project workflow and template provenance summary.", true),
|
|
332
|
+
readItem(projectRoot, "topogram.project.json", "Topology, outputs, template metadata, generator bindings, and implementation provider settings.", true),
|
|
333
|
+
readItem(projectRoot, "topogram.template-policy.json", "Template trust/update policy for attached templates.", false),
|
|
334
|
+
readItem(projectRoot, GENERATOR_POLICY_FILE, "Package-backed generator policy and allowed scopes.", false),
|
|
335
|
+
readItem(projectRoot, TEMPLATE_TRUST_FILE, "Executable implementation trust record, if the template copied implementation code.", Boolean(config.implementation)),
|
|
336
|
+
readItem(projectRoot, TOPOGRAM_IMPORT_FILE, "Brownfield import provenance and source evidence, if this came from import.", Boolean(importSummary)),
|
|
337
|
+
readItem(projectRoot, topogramReadPath, "Canonical Topogram graph source. Use focused query packets for implementation work.", true)
|
|
338
|
+
];
|
|
339
|
+
|
|
340
|
+
const firstCommands = [
|
|
341
|
+
commandItem("npm run agent:brief", "Machine-readable current onboarding guidance."),
|
|
342
|
+
commandItem("npm run doctor", "Check local CLI, package, and catalog setup."),
|
|
343
|
+
commandItem("npm run source:status", "See whether template-derived files diverged locally."),
|
|
344
|
+
commandItem("npm run template:explain", "Understand whether the project is template-attached or detached."),
|
|
345
|
+
commandItem("npm run generator:policy:check", "Validate package-backed generator policy before generation."),
|
|
346
|
+
...(config.implementation ? [
|
|
347
|
+
commandItem("npm run trust:status", "Check executable implementation trust before generation.", "trust")
|
|
348
|
+
] : []),
|
|
349
|
+
commandItem("npm run check", "Validate Topogram, project config, topology, ownership, trust, and generator policy."),
|
|
350
|
+
commandItem("npm run query:list", "Discover focused agent packets."),
|
|
351
|
+
commandItem("npm run query:show -- widget-behavior", "Read a focused UI/widget packet before UI work.", "focused-context"),
|
|
352
|
+
commandItem("npm run generate", "Write generated-owned runtime/app outputs after validation.", "write"),
|
|
353
|
+
commandItem("npm run verify", "Run generated output verification.", "verify"),
|
|
354
|
+
...(importSummary ? [
|
|
355
|
+
commandItem("topogram import check .", "Validate imported workspace provenance.", "import"),
|
|
356
|
+
commandItem("topogram import plan .", "Review import adoption plan.", "import"),
|
|
357
|
+
commandItem("topogram import adopt --list .", "List reviewable adoption selectors.", "import"),
|
|
358
|
+
commandItem("topogram import history . --verify", "Verify import history evidence.", "import")
|
|
359
|
+
] : [])
|
|
360
|
+
];
|
|
361
|
+
|
|
362
|
+
const generatorPolicy = {
|
|
363
|
+
exists: generatorPolicyInfo.exists,
|
|
364
|
+
path: relativeProjectPath(projectRoot, generatorPolicyInfo.path),
|
|
365
|
+
packageBackedGenerators: generatorBindings.length,
|
|
366
|
+
diagnostics: {
|
|
367
|
+
errors: generatorDiagnostics.filter((diagnostic) => diagnostic.severity === "error").length,
|
|
368
|
+
warnings: generatorDiagnostics.filter((diagnostic) => diagnostic.severity === "warning").length,
|
|
369
|
+
items: generatorDiagnostics
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
const templateSummary = {
|
|
374
|
+
id: template.id || null,
|
|
375
|
+
version: template.version || null,
|
|
376
|
+
source: template.source || null,
|
|
377
|
+
sourceSpec: template.sourceSpec || null,
|
|
378
|
+
requested: template.requested || null,
|
|
379
|
+
includesExecutableImplementation: typeof template.includesExecutableImplementation === "boolean"
|
|
380
|
+
? template.includesExecutableImplementation
|
|
381
|
+
: Boolean(config.implementation)
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const payload = {
|
|
385
|
+
type: "agent_brief",
|
|
386
|
+
version: "1",
|
|
387
|
+
project: {
|
|
388
|
+
root: projectRoot,
|
|
389
|
+
topogram: topogramRoot,
|
|
390
|
+
projectConfigPath: projectConfigInfo?.configPath || null,
|
|
391
|
+
packageJson: fs.existsSync(path.join(projectRoot, "package.json")) ? path.join(projectRoot, "package.json") : null
|
|
392
|
+
},
|
|
393
|
+
read_order: readOrder,
|
|
394
|
+
first_commands: firstCommands,
|
|
395
|
+
edit_boundaries: {
|
|
396
|
+
safe_paths: [
|
|
397
|
+
"topogram/**",
|
|
398
|
+
"topogram.project.json",
|
|
399
|
+
"topogram.template-policy.json",
|
|
400
|
+
GENERATOR_POLICY_FILE,
|
|
401
|
+
...(config.implementation ? ["implementation/** after review and trust status"] : [])
|
|
402
|
+
],
|
|
403
|
+
output_boundaries: summarizeOutputBoundaries(config),
|
|
404
|
+
rule: "Edit Topogram and policy files first. Avoid generated-owned output paths unless converting them to maintained ownership."
|
|
405
|
+
},
|
|
406
|
+
workflows: buildWorkflows(config, Boolean(importSummary)),
|
|
407
|
+
file_organization: {
|
|
408
|
+
small: ["topogram/actors", "topogram/entities", "topogram/shapes", "topogram/capabilities", "topogram/widgets", "topogram/projections", "topogram/verifications"],
|
|
409
|
+
large: ["topogram/domains/<domain>", "topogram/shared", "topogram/domains/<domain>/widgets", "topogram/domains/<domain>/projections"],
|
|
410
|
+
parserRule: "Folder layout is for humans and agents; Topogram flattens statements into one graph."
|
|
411
|
+
},
|
|
412
|
+
topology: {
|
|
413
|
+
runtimes: summarizeRuntimes(config),
|
|
414
|
+
outputs: summarizeOutputBoundaries(config)
|
|
415
|
+
},
|
|
416
|
+
template: templateSummary,
|
|
417
|
+
trust: {
|
|
418
|
+
ok: Boolean(trust.ok),
|
|
419
|
+
requiresTrust: Boolean(trust.requiresTrust),
|
|
420
|
+
path: trust.trustPath ? relativeProjectPath(projectRoot, trust.trustPath) : TEMPLATE_TRUST_FILE,
|
|
421
|
+
implementation: trust.implementation || null,
|
|
422
|
+
content: trust.content || null,
|
|
423
|
+
issues: trust.issues || []
|
|
424
|
+
},
|
|
425
|
+
generator_policy: generatorPolicy,
|
|
426
|
+
import: importSummary,
|
|
427
|
+
warnings: []
|
|
428
|
+
};
|
|
429
|
+
payload.warnings = buildWarnings(projectRoot, config, payload.trust, importSummary, generatorPolicy);
|
|
430
|
+
return { ok: true, payload };
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* @param {Record<string, any>} brief
|
|
435
|
+
* @returns {string}
|
|
436
|
+
*/
|
|
437
|
+
export function formatAgentBrief(brief) {
|
|
438
|
+
const lines = [];
|
|
439
|
+
lines.push("Topogram agent brief");
|
|
440
|
+
lines.push(`Project: ${brief.project?.root || "unknown"}`);
|
|
441
|
+
lines.push(`Topogram: ${brief.project?.topogram || "unknown"}`);
|
|
442
|
+
lines.push(`Template: ${brief.template?.id || "none"}${brief.template?.version ? `@${brief.template.version}` : ""}`);
|
|
443
|
+
lines.push(`Implementation trust: ${brief.trust?.requiresTrust ? (brief.trust.ok ? "trusted" : "review required") : "not required"}`);
|
|
444
|
+
lines.push(`Package-backed generators: ${brief.generator_policy?.packageBackedGenerators || 0}`);
|
|
445
|
+
lines.push("");
|
|
446
|
+
lines.push("Read order:");
|
|
447
|
+
for (const item of brief.read_order || []) {
|
|
448
|
+
lines.push(` ${item.exists ? "-" : "- (missing)"} ${item.path} - ${item.reason}`);
|
|
449
|
+
}
|
|
450
|
+
lines.push("");
|
|
451
|
+
lines.push("First commands:");
|
|
452
|
+
for (const item of brief.first_commands || []) {
|
|
453
|
+
lines.push(` - ${item.command} - ${item.reason}`);
|
|
454
|
+
}
|
|
455
|
+
lines.push("");
|
|
456
|
+
lines.push("Edit boundaries:");
|
|
457
|
+
lines.push(` - ${brief.edit_boundaries?.rule || "Edit Topogram first."}`);
|
|
458
|
+
for (const output of brief.edit_boundaries?.output_boundaries || []) {
|
|
459
|
+
lines.push(` - ${output.path}/ (${output.ownership}) - ${output.rule}`);
|
|
460
|
+
}
|
|
461
|
+
lines.push("");
|
|
462
|
+
lines.push("Topology:");
|
|
463
|
+
for (const runtime of brief.topology?.runtimes || []) {
|
|
464
|
+
const edges = [
|
|
465
|
+
runtime.uses_api ? `uses_api=${runtime.uses_api}` : null,
|
|
466
|
+
runtime.uses_database ? `uses_database=${runtime.uses_database}` : null
|
|
467
|
+
].filter(Boolean).join(", ");
|
|
468
|
+
lines.push(` - ${runtime.id}: ${runtime.kind}${runtime.projection ? ` -> ${runtime.projection}` : ""}${runtime.generator ? ` via ${runtime.generator}` : ""}${edges ? ` (${edges})` : ""}`);
|
|
469
|
+
}
|
|
470
|
+
if ((brief.topology?.runtimes || []).length === 0) {
|
|
471
|
+
lines.push(" - No topology runtimes configured.");
|
|
472
|
+
}
|
|
473
|
+
lines.push("");
|
|
474
|
+
lines.push("Workflows:");
|
|
475
|
+
for (const workflow of brief.workflows || []) {
|
|
476
|
+
lines.push(` - ${workflow.title}: ${workflow.rule}`);
|
|
477
|
+
}
|
|
478
|
+
lines.push("");
|
|
479
|
+
lines.push("Verification gates:");
|
|
480
|
+
lines.push(" - npm run check");
|
|
481
|
+
lines.push(" - topogram widget check --json when UI/widget contracts change");
|
|
482
|
+
lines.push(" - topogram widget behavior --json when widget behavior changes");
|
|
483
|
+
lines.push(" - npm run generate");
|
|
484
|
+
lines.push(" - npm run verify");
|
|
485
|
+
if ((brief.warnings || []).length > 0) {
|
|
486
|
+
lines.push("");
|
|
487
|
+
lines.push("Warnings:");
|
|
488
|
+
for (const warning of brief.warnings) {
|
|
489
|
+
lines.push(` - ${warning}`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
lines.push("");
|
|
493
|
+
lines.push("Machine-readable source: topogram agent brief --json");
|
|
494
|
+
return `${lines.join("\n")}\n`;
|
|
495
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function buildAuthHintsQueryPayload(...args: any[]): any;
|
|
2
|
+
export function buildAuthReviewPacketPayload(...args: any[]): any;
|
|
3
|
+
export function buildCanonicalWritesPayloadForChangePlan(...args: any[]): any;
|
|
4
|
+
export function buildCanonicalWritesPayloadForImportPlan(...args: any[]): any;
|
|
5
|
+
export function buildChangePlanPayload(...args: any[]): any;
|
|
6
|
+
export function buildHandoffStatusPayload(...args: any[]): any;
|
|
7
|
+
export function buildImportPlanPayload(...args: any[]): any;
|
|
8
|
+
export function buildLaneStatusPayload(...args: any[]): any;
|
|
9
|
+
export function buildMaintainedConformancePayload(...args: any[]): any;
|
|
10
|
+
export function buildMaintainedDriftPayload(...args: any[]): any;
|
|
11
|
+
export function buildMaintainedRiskSummary(...args: any[]): any;
|
|
12
|
+
export function buildMultiAgentPlanPayload(...args: any[]): any;
|
|
13
|
+
export function buildResolvedWorkflowContextPayload(...args: any[]): any;
|
|
14
|
+
export function buildReviewPacketPayloadForChangePlan(...args: any[]): any;
|
|
15
|
+
export function buildReviewPacketPayloadForImportPlan(...args: any[]): any;
|
|
16
|
+
export function buildRiskSummaryPayload(...args: any[]): any;
|
|
17
|
+
export function buildSeamCheckPayload(...args: any[]): any;
|
|
18
|
+
export function buildSingleAgentPlanPayload(...args: any[]): any;
|
|
19
|
+
export function buildWorkflowPresetActivationPayload(...args: any[]): any;
|
|
20
|
+
export function buildWorkflowPresetCustomizationPayload(...args: any[]): any;
|
|
21
|
+
export function buildWorkflowPresetDiffPayload(...args: any[]): any;
|
|
22
|
+
export function buildWorkflowPresetState(...args: any[]): any;
|
|
23
|
+
export function buildWorkPacketPayload(...args: any[]): any;
|
|
24
|
+
export function classifyRisk(...args: any[]): any;
|
|
25
|
+
export function proceedDecisionFromRisk(...args: any[]): any;
|
|
26
|
+
export function summarizeDiffArtifact(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function compact(...args: any[]): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function unarchive(...args: any[]): any;
|
package/src/catalog.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function catalogEntryPackageSpec(entry: any, version?: string | null): string;
|
|
2
|
+
export function catalogSourceOrDefault(source?: string | null): string;
|
|
3
|
+
export function catalogTemplateListItem(entry: any): any;
|
|
4
|
+
export function buildTopogramSourceStatus(projectRoot: string): any;
|
|
5
|
+
export function checkCatalogSource(source: string): any;
|
|
6
|
+
export function copyCatalogTopogramEntry(entry: any, targetPath: string, options: any): any;
|
|
7
|
+
export function findCatalogEntry(catalog: any, id: string, kind?: "template" | "topogram" | null): any | null;
|
|
8
|
+
export function isCatalogSourceDisabled(source: string | null | undefined): boolean;
|
|
9
|
+
export function loadCatalog(sourceInput?: string | null): any;
|
|
10
|
+
export const TOPOGRAM_SOURCE_FILE: string;
|