@principal-ai/principal-studio-cli 0.37.1 → 0.39.0

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.
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Lets the CLI create/list models without Studio's HTTP bridge running.
6
6
  * Structural validation mirrors the Studio POST gate (construct / mechanism /
7
- * throughlines / detail provenance). File/symbol verification is Studio-only
7
+ * walkthroughs / detail provenance). File/symbol verification is Studio-only
8
8
  * for now and may be empty on CLI-created records until opened/updated there.
9
9
  */
10
- export declare const SUBSYSTEM_EDGE_MECHANISMS: readonly ["imports", "imports_from", "re_exports", "defines", "calls", "extends", "inherits", "implements", "mixes_in", "uses", "method", "references", "contains", "feeds", "produces", "writes", "reads", "watches", "registers-into"];
10
+ export declare const SUBSYSTEM_EDGE_MECHANISMS: readonly ["imports", "calls", "extends", "inherits", "implements", "mixes_in", "uses", "method", "references", "contains", "feeds", "produces", "writes", "reads", "watches", "registers-into"];
11
11
  export declare const SUBSYSTEM_COMPONENT_CONSTRUCTS: readonly ["class", "function", "method", "interface", "type_alias", "enum", "store", "external", "custom_entity"];
12
- export declare const SUBSYSTEM_DETAIL_PROVENANCES: readonly ["verified", "authored"];
12
+ export declare const SUBSYSTEM_DECLARATION_PROVENANCES: readonly ["verified", "authored"];
13
13
  export interface SubsystemModelIndexEntry {
14
14
  id: string;
15
15
  title: string;
@@ -36,8 +36,8 @@ export interface StoredSubsystemModel {
36
36
  title: string;
37
37
  description?: string;
38
38
  components: unknown[];
39
- edges: unknown[];
40
- throughlines?: unknown[];
39
+ relations: unknown[];
40
+ walkthroughs?: unknown[];
41
41
  createdAt: string;
42
42
  updatedAt: string;
43
43
  lastOpenedAt?: string;
@@ -59,8 +59,8 @@ export interface CreateSubsystemModelInput {
59
59
  title: string;
60
60
  description?: string;
61
61
  components: unknown[];
62
- edges: unknown[];
63
- throughlines?: unknown[];
62
+ relations: unknown[];
63
+ walkthroughs?: unknown[];
64
64
  source?: string;
65
65
  repo?: {
66
66
  owner: string;
@@ -70,11 +70,11 @@ export interface CreateSubsystemModelInput {
70
70
  repoRoots?: Record<string, string>;
71
71
  }
72
72
  export declare function subsystemModelFilePath(id: string): string;
73
- export declare function findEdgeMechanismProblems(edges: unknown): string[];
74
- export declare function findThroughlineProblems(edges: unknown, throughlines: unknown): string[];
73
+ export declare function findRelationTypeProblems(relations: unknown): string[];
74
+ export declare function findWalkthroughProblems(walkthroughs: unknown): string[];
75
75
  export declare function findComponentConstructProblems(components: unknown): string[];
76
- export declare function findDetailProvenanceProblems(components: unknown): string[];
77
- export declare function normalizeDetailProvenance(components: unknown): void;
76
+ export declare function findDeclarationProvenanceProblems(components: unknown): string[];
77
+ export declare function normalizeDeclarationProvenance(components: unknown): void;
78
78
  export declare function isRepoRoots(value: unknown): value is Record<string, string>;
79
79
  /** Structural problems that would make Studio reject a POST (empty = valid). */
80
80
  export declare function findCreateProblems(body: Record<string, unknown>): string[];
@@ -82,5 +82,5 @@ export declare function listSubsystemModels(): Promise<SubsystemModelIndexEntry[
82
82
  export declare function getSubsystemModel(id: string): Promise<StoredSubsystemModel | null>;
83
83
  export declare function createSubsystemModel(doc: CreateSubsystemModelInput): Promise<StoredSubsystemModel>;
84
84
  /** Patch an existing record (e.g. stamp a host gist ref after share). */
85
- export declare function updateSubsystemModel(id: string, patch: Partial<Pick<StoredSubsystemModel, 'title' | 'description' | 'components' | 'edges' | 'throughlines' | 'source' | 'repo' | 'repoRoot' | 'repoRoots' | 'gist'>>): Promise<StoredSubsystemModel | null>;
85
+ export declare function updateSubsystemModel(id: string, patch: Partial<Pick<StoredSubsystemModel, 'title' | 'description' | 'components' | 'relations' | 'walkthroughs' | 'source' | 'repo' | 'repoRoot' | 'repoRoots' | 'gist'>>): Promise<StoredSubsystemModel | null>;
86
86
  //# sourceMappingURL=subsystem-model-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subsystem-model-store.d.ts","sourceRoot":"","sources":["../../src/lib/subsystem-model-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subsystem-model-store.d.ts","sourceRoot":"","sources":["../../src/lib/subsystem-model-store.ts"],"names":[],"mappings":"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"}
@@ -4,19 +4,17 @@
4
4
  *
5
5
  * Lets the CLI create/list models without Studio's HTTP bridge running.
6
6
  * Structural validation mirrors the Studio POST gate (construct / mechanism /
7
- * throughlines / detail provenance). File/symbol verification is Studio-only
7
+ * walkthroughs / detail provenance). File/symbol verification is Studio-only
8
8
  * for now and may be empty on CLI-created records until opened/updated there.
9
9
  */
10
10
  import { promises as fs } from 'node:fs';
11
11
  import { homedir } from 'node:os';
12
12
  import { join } from 'node:path';
13
+ import { deriveGraphEdges } from '@principal-ai/subsystems-core';
13
14
  const ROOT = join(homedir(), '.principal', 'subsystem-models');
14
15
  const INDEX_PATH = join(ROOT, '_index.json');
15
16
  export const SUBSYSTEM_EDGE_MECHANISMS = [
16
17
  'imports',
17
- 'imports_from',
18
- 're_exports',
19
- 'defines',
20
18
  'calls',
21
19
  'extends',
22
20
  'inherits',
@@ -44,7 +42,7 @@ export const SUBSYSTEM_COMPONENT_CONSTRUCTS = [
44
42
  'external',
45
43
  'custom_entity',
46
44
  ];
47
- export const SUBSYSTEM_DETAIL_PROVENANCES = ['verified', 'authored'];
45
+ export const SUBSYSTEM_DECLARATION_PROVENANCES = ['verified', 'authored'];
48
46
  function graphId() {
49
47
  const ts = Date.now();
50
48
  const rand = Math.random().toString(36).slice(2, 11);
@@ -59,53 +57,72 @@ export function subsystemModelFilePath(id) {
59
57
  async function ensureDir() {
60
58
  await fs.mkdir(ROOT, { recursive: true });
61
59
  }
62
- export function findEdgeMechanismProblems(edges) {
63
- if (!Array.isArray(edges))
64
- return [];
60
+ const SUBSYSTEM_RELATION_TYPES = [
61
+ 'imports', 'extends', 'inherits',
62
+ 'implements', 'mixes_in', 'method', 'references', 'contains',
63
+ ];
64
+ const SUBSYSTEM_WALKTHROUGH_MECHANISMS = [
65
+ 'calls', 'uses', 'feeds', 'produces', 'writes', 'reads', 'watches', 'registers-into',
66
+ ];
67
+ export function findRelationTypeProblems(relations) {
68
+ if (!Array.isArray(relations))
69
+ return ['relations must be an array'];
65
70
  const problems = [];
66
- for (const edge of edges) {
67
- const e = edge;
68
- if (typeof e?.mechanism === 'string' &&
69
- SUBSYSTEM_EDGE_MECHANISMS.includes(e.mechanism)) {
70
- continue;
71
+ for (const rel of relations) {
72
+ const r = rel;
73
+ if (typeof r?.id !== 'string' || !r.id.trim()) {
74
+ problems.push(`relation ${JSON.stringify(r?.id ?? '<no id>')}: id is required`);
75
+ }
76
+ if (typeof r?.from !== 'string' || !r.from.trim()) {
77
+ problems.push(`relation ${JSON.stringify(r?.id ?? '<no id>')}: from is required`);
78
+ }
79
+ if (typeof r?.to !== 'string' || !r.to.trim()) {
80
+ problems.push(`relation ${JSON.stringify(r?.id ?? '<no id>')}: to is required`);
81
+ }
82
+ if (typeof r?.relationType !== 'string' ||
83
+ !SUBSYSTEM_RELATION_TYPES.includes(r.relationType)) {
84
+ problems.push(`relation ${JSON.stringify(r?.id ?? '<no id>')}: unknown relationType ${JSON.stringify(r?.relationType)}`);
71
85
  }
72
- problems.push(`edge ${JSON.stringify(e?.id ?? '<no id>')}: unknown mechanism ${JSON.stringify(e?.mechanism)} — allowed: ${SUBSYSTEM_EDGE_MECHANISMS.join(', ')}`);
73
86
  }
74
87
  return problems;
75
88
  }
76
- export function findThroughlineProblems(edges, throughlines) {
77
- if (throughlines === undefined)
89
+ export function findWalkthroughProblems(walkthroughs) {
90
+ if (walkthroughs === undefined)
78
91
  return [];
79
- if (!Array.isArray(throughlines))
80
- return ['throughlines must be an array'];
81
- const edgeIds = new Set((Array.isArray(edges) ? edges : [])
82
- .map((e) => e?.id)
83
- .filter((id) => typeof id === 'string'));
92
+ if (!Array.isArray(walkthroughs))
93
+ return ['walkthroughs must be an array'];
84
94
  const problems = [];
85
- for (const tl of throughlines) {
86
- const t = tl;
87
- const label = JSON.stringify(t?.id ?? '<no id>');
88
- if (typeof t?.id !== 'string' || !t.id.trim()) {
89
- problems.push(`throughline ${label}: id is required`);
95
+ for (const wt of walkthroughs) {
96
+ const w = wt;
97
+ const label = JSON.stringify(w?.id ?? '<no id>');
98
+ if (typeof w?.id !== 'string' || !w.id.trim()) {
99
+ problems.push(`walkthrough ${label}: id is required`);
90
100
  continue;
91
101
  }
92
- if (typeof t?.title !== 'string' || !t.title.trim()) {
93
- problems.push(`throughline ${label}: title is required`);
102
+ if (typeof w?.title !== 'string' || !w.title.trim()) {
103
+ problems.push(`walkthrough ${label}: title is required`);
94
104
  }
95
- if (!Array.isArray(t.steps)) {
96
- problems.push(`throughline ${label}: steps array is required`);
105
+ if (!Array.isArray(w.steps)) {
106
+ problems.push(`walkthrough ${label}: steps array is required`);
97
107
  continue;
98
108
  }
99
- t.steps.forEach((step, i) => {
109
+ w.steps.forEach((step, i) => {
100
110
  const s = step;
101
- if (typeof s?.edgeId !== 'string' || !edgeIds.has(s.edgeId)) {
102
- problems.push(`throughline ${label}: step ${i} edgeId ${JSON.stringify(s?.edgeId ?? '<missing>')} does not match any edge in the graph`);
111
+ if (typeof s?.from !== 'string' || !s.from.trim()) {
112
+ problems.push(`walkthrough ${label}: step ${i} from is required`);
113
+ }
114
+ if (typeof s?.to !== 'string' || !s.to.trim()) {
115
+ problems.push(`walkthrough ${label}: step ${i} to is required`);
116
+ }
117
+ if (typeof s?.mechanism !== 'string' ||
118
+ !SUBSYSTEM_WALKTHROUGH_MECHANISMS.includes(s.mechanism)) {
119
+ problems.push(`walkthrough ${label}: step ${i} unknown mechanism ${JSON.stringify(s?.mechanism)}`);
103
120
  }
104
121
  if (typeof s?.file !== 'string' || !s.file.trim()) {
105
- problems.push(`throughline ${label}: step ${i} file is required (edgeId ${JSON.stringify(s?.edgeId ?? '<missing>')})`);
122
+ problems.push(`walkthrough ${label}: step ${i} file is required`);
106
123
  }
107
124
  else if (typeof s?.line !== 'number' || !Number.isInteger(s.line) || s.line < 1) {
108
- problems.push(`throughline ${label}: step ${i} line must be a positive 1-based integer (edgeId ${JSON.stringify(s?.edgeId ?? '<missing>')}, file ${JSON.stringify(s?.file)})`);
125
+ problems.push(`walkthrough ${label}: step ${i} line must be a positive 1-based integer`);
109
126
  }
110
127
  });
111
128
  }
@@ -125,51 +142,54 @@ export function findComponentConstructProblems(components) {
125
142
  }
126
143
  return problems;
127
144
  }
128
- export function findDetailProvenanceProblems(components) {
145
+ export function findDeclarationProvenanceProblems(components) {
129
146
  if (!Array.isArray(components))
130
147
  return [];
131
148
  const problems = [];
132
149
  for (const component of components) {
133
150
  const c = component;
134
- if (!c || typeof c !== 'object' || !c['detail'])
151
+ if (!c || typeof c !== 'object')
152
+ continue;
153
+ if (!c['declaration'])
135
154
  continue;
136
- const p = c['detailProvenance'];
155
+ const p = c['declarationProvenance'];
137
156
  if (p === undefined)
138
157
  continue;
139
- if (typeof p === 'string' && SUBSYSTEM_DETAIL_PROVENANCES.includes(p)) {
158
+ if (typeof p === 'string' &&
159
+ SUBSYSTEM_DECLARATION_PROVENANCES.includes(p)) {
140
160
  continue;
141
161
  }
142
- problems.push(`component ${JSON.stringify(String(c['id'] ?? '<no id>'))}: invalid detailProvenance ${JSON.stringify(p)} — allowed: ${SUBSYSTEM_DETAIL_PROVENANCES.join(', ')}. Hand-authored details must be "authored"; "verified" is reserved for tool-extracted data.`);
162
+ problems.push(`component ${JSON.stringify(String(c['id'] ?? '<no id>'))}: invalid declarationProvenance ${JSON.stringify(p)} — allowed: ${SUBSYSTEM_DECLARATION_PROVENANCES.join(', ')}. Hand-authored declarations must be "authored"; "verified" is reserved for tool-extracted data.`);
143
163
  }
144
164
  return problems;
145
165
  }
146
- export function normalizeDetailProvenance(components) {
166
+ export function normalizeDeclarationProvenance(components) {
147
167
  if (!Array.isArray(components))
148
168
  return;
149
169
  for (const component of components) {
150
170
  const c = component;
151
171
  if (!c || typeof c !== 'object')
152
172
  continue;
153
- const detail = c['detail'];
154
- if (!detail || typeof detail !== 'object') {
155
- delete c['detailProvenance'];
173
+ const declaration = c['declaration'];
174
+ if (!declaration || typeof declaration !== 'object') {
175
+ delete c['declarationProvenance'];
156
176
  continue;
157
177
  }
158
- const p = c['detailProvenance'];
178
+ const p = c['declarationProvenance'];
159
179
  if (p !== 'verified' && p !== 'authored')
160
- c['detailProvenance'] = 'authored';
161
- const kind = detail['kind'];
180
+ c['declarationProvenance'] = 'authored';
181
+ const kind = declaration['kind'];
162
182
  const arrays = {
163
183
  function: ['parameters', 'callers', 'callees'],
164
184
  method: ['parameters'],
165
185
  class: ['methods', 'properties', 'extends', 'implements', 'instantiations', 'references'],
166
186
  type: ['properties', 'usedBy', 'implementors'],
167
- module: ['imports', 'exports', 'symbols'],
168
187
  custom_entity: ['attributes'],
188
+ store: ['properties'],
169
189
  };
170
190
  for (const key of arrays[String(kind)] ?? []) {
171
- if (!Array.isArray(detail[key]))
172
- detail[key] = [];
191
+ if (!Array.isArray(declaration[key]))
192
+ declaration[key] = [];
173
193
  }
174
194
  }
175
195
  }
@@ -187,16 +207,16 @@ export function findCreateProblems(body) {
187
207
  if (!Array.isArray(body['components'])) {
188
208
  problems.push('components array is required');
189
209
  }
190
- if (!Array.isArray(body['edges'])) {
191
- problems.push('edges array is required');
210
+ if (!Array.isArray(body['relations'])) {
211
+ problems.push('relations array is required');
192
212
  }
193
213
  if (problems.length > 0)
194
214
  return problems;
195
215
  return [
196
216
  ...findComponentConstructProblems(body['components']),
197
- ...findDetailProvenanceProblems(body['components']),
198
- ...findEdgeMechanismProblems(body['edges']),
199
- ...findThroughlineProblems(body['edges'], body['throughlines']),
217
+ ...findDeclarationProvenanceProblems(body['components']),
218
+ ...findRelationTypeProblems(body['relations']),
219
+ ...findWalkthroughProblems(body['walkthroughs']),
200
220
  ];
201
221
  }
202
222
  function indexEntryFor(record) {
@@ -205,7 +225,10 @@ function indexEntryFor(record) {
205
225
  title: record.title,
206
226
  description: record.description,
207
227
  componentCount: record.components.length,
208
- edgeCount: record.edges.length,
228
+ edgeCount: deriveGraphEdges({
229
+ relations: record.relations,
230
+ walkthroughs: record.walkthroughs,
231
+ }).length,
209
232
  createdAt: record.createdAt,
210
233
  updatedAt: record.updatedAt,
211
234
  lastOpenedAt: record.lastOpenedAt,
@@ -281,7 +304,7 @@ export async function getSubsystemModel(id) {
281
304
  }
282
305
  export async function createSubsystemModel(doc) {
283
306
  await ensureDir();
284
- normalizeDetailProvenance(doc.components);
307
+ normalizeDeclarationProvenance(doc.components);
285
308
  const now = new Date().toISOString();
286
309
  const record = {
287
310
  ...doc,
@@ -299,7 +322,7 @@ export async function updateSubsystemModel(id, patch) {
299
322
  if (!existing)
300
323
  return null;
301
324
  if (patch.components !== undefined)
302
- normalizeDetailProvenance(patch.components);
325
+ normalizeDeclarationProvenance(patch.components);
303
326
  const updated = {
304
327
  ...existing,
305
328
  ...patch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/principal-studio-cli",
3
- "version": "0.37.1",
3
+ "version": "0.39.0",
4
4
  "description": "Principal AI CLI — subsystem models, Subsystems Studio, trails, and agent sessions",
5
5
  "main": "dist/index.cjs",
6
6
  "types": "dist/index.d.ts",
@@ -36,7 +36,7 @@
36
36
  "@principal-ai/codebase-composition": "^0.2.57",
37
37
  "@principal-ai/file-city-builder": "^0.5.0",
38
38
  "@principal-ai/repository-abstraction": "^0.5.7",
39
- "@principal-ai/subsystems-core": "0.31.4",
39
+ "@principal-ai/subsystems-core": "0.33.0",
40
40
  "better-sqlite3": "^13.0.0",
41
41
  "chalk": "5.6.2",
42
42
  "commander": "14.0.2",
@@ -45,7 +45,7 @@
45
45
  "js-yaml": "4.1.1"
46
46
  },
47
47
  "optionalDependencies": {
48
- "@principal-ai/subsystems-studio": "^0.6.7"
48
+ "@principal-ai/subsystems-studio": "0.6.10"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/better-sqlite3": "^7.6.13",