@workflow-cannon/workspace-kit 0.7.0 → 0.9.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.
- package/README.md +5 -4
- package/dist/cli/run-command.d.ts +11 -0
- package/dist/cli/run-command.js +138 -0
- package/dist/cli.js +18 -135
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/module-contract.d.ts +13 -0
- package/dist/core/config-cli.js +4 -4
- package/dist/core/config-metadata.js +199 -5
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +6 -0
- package/dist/core/instruction-template-mapper.d.ts +9 -0
- package/dist/core/instruction-template-mapper.js +35 -0
- package/dist/core/lineage-contract.d.ts +1 -1
- package/dist/core/lineage-contract.js +1 -1
- package/dist/core/policy.d.ts +13 -2
- package/dist/core/policy.js +42 -25
- package/dist/core/response-template-contract.d.ts +15 -0
- package/dist/core/response-template-contract.js +10 -0
- package/dist/core/response-template-registry.d.ts +4 -0
- package/dist/core/response-template-registry.js +44 -0
- package/dist/core/response-template-shaping.d.ts +6 -0
- package/dist/core/response-template-shaping.js +128 -0
- package/dist/core/session-policy.d.ts +18 -0
- package/dist/core/session-policy.js +57 -0
- package/dist/core/transcript-completion-hook.d.ts +7 -0
- package/dist/core/transcript-completion-hook.js +128 -0
- package/dist/core/workspace-kit-config.d.ts +2 -1
- package/dist/core/workspace-kit-config.js +19 -23
- package/dist/modules/approvals/index.js +2 -2
- package/dist/modules/documentation/runtime.js +413 -20
- package/dist/modules/improvement/generate-recommendations-runtime.d.ts +7 -0
- package/dist/modules/improvement/generate-recommendations-runtime.js +37 -4
- package/dist/modules/improvement/improvement-state.d.ts +10 -1
- package/dist/modules/improvement/improvement-state.js +36 -7
- package/dist/modules/improvement/index.js +70 -23
- package/dist/modules/improvement/ingest.js +2 -1
- package/dist/modules/improvement/transcript-redaction.d.ts +4 -0
- package/dist/modules/improvement/transcript-redaction.js +10 -0
- package/dist/modules/improvement/transcript-sync-runtime.d.ts +42 -1
- package/dist/modules/improvement/transcript-sync-runtime.js +215 -9
- package/dist/modules/index.d.ts +1 -1
- package/dist/modules/index.js +1 -1
- package/dist/modules/task-engine/index.d.ts +0 -2
- package/dist/modules/task-engine/index.js +4 -78
- package/package.json +6 -2
- package/src/modules/documentation/README.md +39 -0
- package/src/modules/documentation/RULES.md +70 -0
- package/src/modules/documentation/config.md +14 -0
- package/src/modules/documentation/index.ts +120 -0
- package/src/modules/documentation/instructions/document-project.md +44 -0
- package/src/modules/documentation/instructions/documentation-maintainer.md +81 -0
- package/src/modules/documentation/instructions/generate-document.md +44 -0
- package/src/modules/documentation/runtime.ts +870 -0
- package/src/modules/documentation/schemas/documentation-schema.md +54 -0
- package/src/modules/documentation/state.md +8 -0
- package/src/modules/documentation/templates/AGENTS.md +84 -0
- package/src/modules/documentation/templates/ARCHITECTURE.md +71 -0
- package/src/modules/documentation/templates/PRINCIPLES.md +122 -0
- package/src/modules/documentation/templates/RELEASING.md +96 -0
- package/src/modules/documentation/templates/ROADMAP.md +131 -0
- package/src/modules/documentation/templates/SECURITY.md +53 -0
- package/src/modules/documentation/templates/SUPPORT.md +40 -0
- package/src/modules/documentation/templates/TERMS.md +61 -0
- package/src/modules/documentation/templates/runbooks/consumer-cadence.md +55 -0
- package/src/modules/documentation/templates/runbooks/parity-validation-flow.md +68 -0
- package/src/modules/documentation/templates/runbooks/release-channels.md +30 -0
- package/src/modules/documentation/templates/workbooks/phase2-config-policy-workbook.md +42 -0
- package/src/modules/documentation/templates/workbooks/task-engine-workbook.md +42 -0
- package/src/modules/documentation/templates/workbooks/transcript-automation-baseline.md +68 -0
- package/src/modules/documentation/types.ts +51 -0
- package/dist/modules/task-engine/generator.d.ts +0 -3
- package/dist/modules/task-engine/generator.js +0 -118
- package/dist/modules/task-engine/importer.d.ts +0 -8
- package/dist/modules/task-engine/importer.js +0 -163
|
@@ -32,8 +32,8 @@ const REGISTRY = {
|
|
|
32
32
|
"improvement.transcripts.sourcePath": {
|
|
33
33
|
key: "improvement.transcripts.sourcePath",
|
|
34
34
|
type: "string",
|
|
35
|
-
description: "
|
|
36
|
-
default: "
|
|
35
|
+
description: "Optional relative path to transcript JSONL source. When empty, sync uses discoveryPaths (repo-relative, then Cursor global ~/.cursor/projects/<slug>/agent-transcripts).",
|
|
36
|
+
default: "",
|
|
37
37
|
domainScope: "project",
|
|
38
38
|
owningModule: "improvement",
|
|
39
39
|
sensitive: false,
|
|
@@ -80,6 +80,125 @@ const REGISTRY = {
|
|
|
80
80
|
requiresApproval: false,
|
|
81
81
|
exposure: "maintainer",
|
|
82
82
|
writableLayers: ["project", "user"]
|
|
83
|
+
},
|
|
84
|
+
"improvement.cadence.maxRecommendationCandidatesPerRun": {
|
|
85
|
+
key: "improvement.cadence.maxRecommendationCandidatesPerRun",
|
|
86
|
+
type: "number",
|
|
87
|
+
description: "Upper bound on new improvement tasks created per generate-recommendations run (safety cap; direct runs still respect dedupe).",
|
|
88
|
+
default: 500,
|
|
89
|
+
domainScope: "project",
|
|
90
|
+
owningModule: "improvement",
|
|
91
|
+
sensitive: false,
|
|
92
|
+
requiresRestart: false,
|
|
93
|
+
requiresApproval: false,
|
|
94
|
+
exposure: "maintainer",
|
|
95
|
+
writableLayers: ["project", "user"]
|
|
96
|
+
},
|
|
97
|
+
"improvement.transcripts.maxFilesPerSync": {
|
|
98
|
+
key: "improvement.transcripts.maxFilesPerSync",
|
|
99
|
+
type: "number",
|
|
100
|
+
description: "Maximum JSONL transcript files processed per sync (deterministic order).",
|
|
101
|
+
default: 5000,
|
|
102
|
+
domainScope: "project",
|
|
103
|
+
owningModule: "improvement",
|
|
104
|
+
sensitive: false,
|
|
105
|
+
requiresRestart: false,
|
|
106
|
+
requiresApproval: false,
|
|
107
|
+
exposure: "maintainer",
|
|
108
|
+
writableLayers: ["project", "user"]
|
|
109
|
+
},
|
|
110
|
+
"improvement.transcripts.maxBytesPerFile": {
|
|
111
|
+
key: "improvement.transcripts.maxBytesPerFile",
|
|
112
|
+
type: "number",
|
|
113
|
+
description: "Skip transcript files larger than this many bytes during sync.",
|
|
114
|
+
default: 50_000_000,
|
|
115
|
+
domainScope: "project",
|
|
116
|
+
owningModule: "improvement",
|
|
117
|
+
sensitive: false,
|
|
118
|
+
requiresRestart: false,
|
|
119
|
+
requiresApproval: false,
|
|
120
|
+
exposure: "maintainer",
|
|
121
|
+
writableLayers: ["project", "user"]
|
|
122
|
+
},
|
|
123
|
+
"improvement.transcripts.maxTotalScanBytes": {
|
|
124
|
+
key: "improvement.transcripts.maxTotalScanBytes",
|
|
125
|
+
type: "number",
|
|
126
|
+
description: "Approximate cap on total bytes read for hashing during one sync.",
|
|
127
|
+
default: 500_000_000,
|
|
128
|
+
domainScope: "project",
|
|
129
|
+
owningModule: "improvement",
|
|
130
|
+
sensitive: false,
|
|
131
|
+
requiresRestart: false,
|
|
132
|
+
requiresApproval: false,
|
|
133
|
+
exposure: "maintainer",
|
|
134
|
+
writableLayers: ["project", "user"]
|
|
135
|
+
},
|
|
136
|
+
"improvement.transcripts.discoveryPaths": {
|
|
137
|
+
key: "improvement.transcripts.discoveryPaths",
|
|
138
|
+
type: "array",
|
|
139
|
+
description: "Ordered relative paths tried when improvement.transcripts.sourcePath is unset (first existing wins). After these, sync tries Cursor global ~/.cursor/projects/<slug>/agent-transcripts.",
|
|
140
|
+
default: [],
|
|
141
|
+
domainScope: "project",
|
|
142
|
+
owningModule: "improvement",
|
|
143
|
+
sensitive: false,
|
|
144
|
+
requiresRestart: false,
|
|
145
|
+
requiresApproval: false,
|
|
146
|
+
exposure: "maintainer",
|
|
147
|
+
writableLayers: ["project", "user"]
|
|
148
|
+
},
|
|
149
|
+
"improvement.hooks.afterTaskCompleted": {
|
|
150
|
+
key: "improvement.hooks.afterTaskCompleted",
|
|
151
|
+
type: "string",
|
|
152
|
+
description: "Optional background transcript sync after task-engine transition to completed: off (default), sync, or ingest (ingest requires WORKSPACE_KIT_POLICY_APPROVAL in env).",
|
|
153
|
+
default: "off",
|
|
154
|
+
allowedValues: ["off", "sync", "ingest"],
|
|
155
|
+
domainScope: "project",
|
|
156
|
+
owningModule: "improvement",
|
|
157
|
+
sensitive: false,
|
|
158
|
+
requiresRestart: false,
|
|
159
|
+
requiresApproval: false,
|
|
160
|
+
exposure: "maintainer",
|
|
161
|
+
writableLayers: ["project", "user"]
|
|
162
|
+
},
|
|
163
|
+
"responseTemplates.enforcementMode": {
|
|
164
|
+
key: "responseTemplates.enforcementMode",
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "Whether unknown/mismatched response templates fail commands (`strict`) or only emit warnings (`advisory`).",
|
|
167
|
+
default: "advisory",
|
|
168
|
+
allowedValues: ["advisory", "strict"],
|
|
169
|
+
domainScope: "project",
|
|
170
|
+
owningModule: "workspace-kit",
|
|
171
|
+
sensitive: false,
|
|
172
|
+
requiresRestart: false,
|
|
173
|
+
requiresApproval: false,
|
|
174
|
+
exposure: "maintainer",
|
|
175
|
+
writableLayers: ["project", "user"]
|
|
176
|
+
},
|
|
177
|
+
"responseTemplates.defaultTemplateId": {
|
|
178
|
+
key: "responseTemplates.defaultTemplateId",
|
|
179
|
+
type: "string",
|
|
180
|
+
description: "Builtin response template id applied when a run does not specify one.",
|
|
181
|
+
default: "default",
|
|
182
|
+
domainScope: "project",
|
|
183
|
+
owningModule: "workspace-kit",
|
|
184
|
+
sensitive: false,
|
|
185
|
+
requiresRestart: false,
|
|
186
|
+
requiresApproval: false,
|
|
187
|
+
exposure: "maintainer",
|
|
188
|
+
writableLayers: ["project", "user"]
|
|
189
|
+
},
|
|
190
|
+
"responseTemplates.commandOverrides": {
|
|
191
|
+
key: "responseTemplates.commandOverrides",
|
|
192
|
+
type: "object",
|
|
193
|
+
description: "Map of module command name to builtin response template id.",
|
|
194
|
+
default: {},
|
|
195
|
+
domainScope: "project",
|
|
196
|
+
owningModule: "workspace-kit",
|
|
197
|
+
sensitive: false,
|
|
198
|
+
requiresRestart: false,
|
|
199
|
+
requiresApproval: false,
|
|
200
|
+
exposure: "maintainer",
|
|
201
|
+
writableLayers: ["project", "user"]
|
|
83
202
|
}
|
|
84
203
|
};
|
|
85
204
|
export function getConfigKeyMetadata(key) {
|
|
@@ -120,6 +239,13 @@ export function validateValueForMetadata(meta, value) {
|
|
|
120
239
|
}
|
|
121
240
|
}
|
|
122
241
|
}
|
|
242
|
+
if (meta.key === "improvement.transcripts.discoveryPaths") {
|
|
243
|
+
for (const item of value) {
|
|
244
|
+
if (typeof item !== "string" || item.trim().length === 0) {
|
|
245
|
+
throw new Error(`config-type-error(${meta.key}): array entries must be non-empty strings`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
123
249
|
return;
|
|
124
250
|
}
|
|
125
251
|
if (meta.type === "string" && typeof value !== "string") {
|
|
@@ -135,6 +261,16 @@ export function validateValueForMetadata(meta, value) {
|
|
|
135
261
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
136
262
|
throw typeError(meta.key, "object", value);
|
|
137
263
|
}
|
|
264
|
+
if (meta.key === "responseTemplates.commandOverrides") {
|
|
265
|
+
for (const [k, v] of Object.entries(value)) {
|
|
266
|
+
if (typeof k !== "string" || !k.trim()) {
|
|
267
|
+
throw new Error(`config-type-error(${meta.key}): keys must be non-empty strings`);
|
|
268
|
+
}
|
|
269
|
+
if (typeof v !== "string" || !v.trim()) {
|
|
270
|
+
throw new Error(`config-type-error(${meta.key}): values must be non-empty strings`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
138
274
|
}
|
|
139
275
|
if (meta.allowedValues && meta.allowedValues.length > 0) {
|
|
140
276
|
if (!meta.allowedValues.some((v) => deepEqualLoose(v, value))) {
|
|
@@ -161,6 +297,7 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
161
297
|
"documentation",
|
|
162
298
|
"policy",
|
|
163
299
|
"improvement",
|
|
300
|
+
"responseTemplates",
|
|
164
301
|
"modules"
|
|
165
302
|
]);
|
|
166
303
|
for (const k of Object.keys(data)) {
|
|
@@ -223,7 +360,7 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
223
360
|
}
|
|
224
361
|
const imp = improvement;
|
|
225
362
|
for (const k of Object.keys(imp)) {
|
|
226
|
-
if (k !== "transcripts" && k !== "cadence") {
|
|
363
|
+
if (k !== "transcripts" && k !== "cadence" && k !== "hooks") {
|
|
227
364
|
throw new Error(`config-invalid(${label}): unknown improvement.${k}`);
|
|
228
365
|
}
|
|
229
366
|
}
|
|
@@ -235,7 +372,12 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
235
372
|
}
|
|
236
373
|
const tr = imp.transcripts;
|
|
237
374
|
for (const k of Object.keys(tr)) {
|
|
238
|
-
if (k !== "sourcePath" &&
|
|
375
|
+
if (k !== "sourcePath" &&
|
|
376
|
+
k !== "archivePath" &&
|
|
377
|
+
k !== "maxFilesPerSync" &&
|
|
378
|
+
k !== "maxBytesPerFile" &&
|
|
379
|
+
k !== "maxTotalScanBytes" &&
|
|
380
|
+
k !== "discoveryPaths") {
|
|
239
381
|
throw new Error(`config-invalid(${label}): unknown improvement.transcripts.${k}`);
|
|
240
382
|
}
|
|
241
383
|
}
|
|
@@ -245,6 +387,18 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
245
387
|
if (tr.archivePath !== undefined) {
|
|
246
388
|
validateValueForMetadata(REGISTRY["improvement.transcripts.archivePath"], tr.archivePath);
|
|
247
389
|
}
|
|
390
|
+
if (tr.maxFilesPerSync !== undefined) {
|
|
391
|
+
validateValueForMetadata(REGISTRY["improvement.transcripts.maxFilesPerSync"], tr.maxFilesPerSync);
|
|
392
|
+
}
|
|
393
|
+
if (tr.maxBytesPerFile !== undefined) {
|
|
394
|
+
validateValueForMetadata(REGISTRY["improvement.transcripts.maxBytesPerFile"], tr.maxBytesPerFile);
|
|
395
|
+
}
|
|
396
|
+
if (tr.maxTotalScanBytes !== undefined) {
|
|
397
|
+
validateValueForMetadata(REGISTRY["improvement.transcripts.maxTotalScanBytes"], tr.maxTotalScanBytes);
|
|
398
|
+
}
|
|
399
|
+
if (tr.discoveryPaths !== undefined) {
|
|
400
|
+
validateValueForMetadata(REGISTRY["improvement.transcripts.discoveryPaths"], tr.discoveryPaths);
|
|
401
|
+
}
|
|
248
402
|
}
|
|
249
403
|
if (imp.cadence !== undefined) {
|
|
250
404
|
if (typeof imp.cadence !== "object" || imp.cadence === null || Array.isArray(imp.cadence)) {
|
|
@@ -252,7 +406,7 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
252
406
|
}
|
|
253
407
|
const cd = imp.cadence;
|
|
254
408
|
for (const k of Object.keys(cd)) {
|
|
255
|
-
if (k !== "minIntervalMinutes" && k !== "skipIfNoNewTranscripts") {
|
|
409
|
+
if (k !== "minIntervalMinutes" && k !== "skipIfNoNewTranscripts" && k !== "maxRecommendationCandidatesPerRun") {
|
|
256
410
|
throw new Error(`config-invalid(${label}): unknown improvement.cadence.${k}`);
|
|
257
411
|
}
|
|
258
412
|
}
|
|
@@ -262,6 +416,46 @@ export function validatePersistedConfigDocument(data, label) {
|
|
|
262
416
|
if (cd.skipIfNoNewTranscripts !== undefined) {
|
|
263
417
|
validateValueForMetadata(REGISTRY["improvement.cadence.skipIfNoNewTranscripts"], cd.skipIfNoNewTranscripts);
|
|
264
418
|
}
|
|
419
|
+
if (cd.maxRecommendationCandidatesPerRun !== undefined) {
|
|
420
|
+
validateValueForMetadata(REGISTRY["improvement.cadence.maxRecommendationCandidatesPerRun"], cd.maxRecommendationCandidatesPerRun);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (imp.hooks !== undefined) {
|
|
424
|
+
if (typeof imp.hooks !== "object" || imp.hooks === null || Array.isArray(imp.hooks)) {
|
|
425
|
+
throw new Error(`config-invalid(${label}): improvement.hooks must be an object`);
|
|
426
|
+
}
|
|
427
|
+
const hk = imp.hooks;
|
|
428
|
+
for (const k of Object.keys(hk)) {
|
|
429
|
+
if (k !== "afterTaskCompleted") {
|
|
430
|
+
throw new Error(`config-invalid(${label}): unknown improvement.hooks.${k}`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (hk.afterTaskCompleted !== undefined) {
|
|
434
|
+
validateValueForMetadata(REGISTRY["improvement.hooks.afterTaskCompleted"], hk.afterTaskCompleted);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const responseTemplates = data.responseTemplates;
|
|
439
|
+
if (responseTemplates !== undefined) {
|
|
440
|
+
if (typeof responseTemplates !== "object" ||
|
|
441
|
+
responseTemplates === null ||
|
|
442
|
+
Array.isArray(responseTemplates)) {
|
|
443
|
+
throw new Error(`config-invalid(${label}): responseTemplates must be an object`);
|
|
444
|
+
}
|
|
445
|
+
const rt = responseTemplates;
|
|
446
|
+
for (const k of Object.keys(rt)) {
|
|
447
|
+
if (k !== "enforcementMode" && k !== "defaultTemplateId" && k !== "commandOverrides") {
|
|
448
|
+
throw new Error(`config-invalid(${label}): unknown responseTemplates.${k}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (rt.enforcementMode !== undefined) {
|
|
452
|
+
validateValueForMetadata(REGISTRY["responseTemplates.enforcementMode"], rt.enforcementMode);
|
|
453
|
+
}
|
|
454
|
+
if (rt.defaultTemplateId !== undefined) {
|
|
455
|
+
validateValueForMetadata(REGISTRY["responseTemplates.defaultTemplateId"], rt.defaultTemplateId);
|
|
456
|
+
}
|
|
457
|
+
if (rt.commandOverrides !== undefined) {
|
|
458
|
+
validateValueForMetadata(REGISTRY["responseTemplates.commandOverrides"], rt.commandOverrides);
|
|
265
459
|
}
|
|
266
460
|
}
|
|
267
461
|
}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ export { ModuleRegistry, ModuleRegistryError, validateModuleSet, type ModuleRegi
|
|
|
2
2
|
export { ModuleCommandRouter, ModuleCommandRouterError, type ModuleCommandDescriptor, type ModuleCommandRouterOptions } from "./module-command-router.js";
|
|
3
3
|
export { buildBaseConfigLayers, deepMerge, envToConfigOverlay, explainConfigPath, getAtPath, getProjectConfigPath, getUserConfigFilePath, KIT_CONFIG_DEFAULTS, loadUserLayer, mergeConfigLayers, MODULE_CONFIG_CONTRIBUTIONS, normalizeConfigForExport, PROJECT_CONFIG_REL, resolveWorkspaceConfigWithLayers, stableStringifyConfig, type ConfigLayer, type ConfigLayerId, type EffectiveWorkspaceConfig, type ExplainConfigResult, type ResolveWorkspaceConfigOptions } from "./workspace-kit-config.js";
|
|
4
4
|
export { appendPolicyTrace, getExtraSensitiveModuleCommandsFromEffective, getOperationIdForCommand, isSensitiveModuleCommand, isSensitiveModuleCommandForEffective, parsePolicyApproval, parsePolicyApprovalFromEnv, POLICY_TRACE_SCHEMA_VERSION, resolveActor, resolvePolicyOperationIdForCommand, type PolicyOperationId, type PolicyTraceRecord, type PolicyTraceRecordInput } from "./policy.js";
|
|
5
|
+
export { getSessionGrant, loadSessionPolicyDocument, recordSessionGrant, resolveSessionId, SESSION_POLICY_SCHEMA_VERSION, type SessionPolicyDocument, type SessionPolicyGrant } from "./session-policy.js";
|
|
6
|
+
export { parseTemplateDirectiveFromText } from "./instruction-template-mapper.js";
|
|
7
|
+
export { RESPONSE_TEMPLATE_CONTRACT_VERSION, MAX_TEMPLATE_WARNING_LENGTH, truncateTemplateWarning, type ResponseTemplateDefinition, type ResponseTemplateEnforcementMode } from "./response-template-contract.js";
|
|
8
|
+
export { allBuiltinDefinitions, getResponseTemplateDefinition, listBuiltinResponseTemplateIds } from "./response-template-registry.js";
|
|
9
|
+
export { applyResponseTemplateApplication } from "./response-template-shaping.js";
|
|
10
|
+
export { maybeSpawnTranscriptHookAfterCompletion, readAfterTaskCompletedHook, resolveWorkspaceKitCli } from "./transcript-completion-hook.js";
|
|
5
11
|
export { assertWritableKey, getConfigKeyMetadata, getConfigRegistryExport, listConfigMetadata, validatePersistedConfigDocument, validateValueForMetadata, type ConfigKeyExposure, type ConfigKeyMetadata, type ConfigValueType } from "./config-metadata.js";
|
|
6
12
|
export { appendConfigMutation, CONFIG_MUTATIONS_SCHEMA_VERSION, summarizeForEvidence, type ConfigMutationRecord } from "./config-mutations.js";
|
|
7
13
|
export { generateConfigReferenceDocs, runWorkspaceConfigCli, type ConfigCliIo } from "./config-cli.js";
|
package/dist/core/index.js
CHANGED
|
@@ -2,6 +2,12 @@ export { ModuleRegistry, ModuleRegistryError, validateModuleSet } from "./module
|
|
|
2
2
|
export { ModuleCommandRouter, ModuleCommandRouterError } from "./module-command-router.js";
|
|
3
3
|
export { buildBaseConfigLayers, deepMerge, envToConfigOverlay, explainConfigPath, getAtPath, getProjectConfigPath, getUserConfigFilePath, KIT_CONFIG_DEFAULTS, loadUserLayer, mergeConfigLayers, MODULE_CONFIG_CONTRIBUTIONS, normalizeConfigForExport, PROJECT_CONFIG_REL, resolveWorkspaceConfigWithLayers, stableStringifyConfig } from "./workspace-kit-config.js";
|
|
4
4
|
export { appendPolicyTrace, getExtraSensitiveModuleCommandsFromEffective, getOperationIdForCommand, isSensitiveModuleCommand, isSensitiveModuleCommandForEffective, parsePolicyApproval, parsePolicyApprovalFromEnv, POLICY_TRACE_SCHEMA_VERSION, resolveActor, resolvePolicyOperationIdForCommand } from "./policy.js";
|
|
5
|
+
export { getSessionGrant, loadSessionPolicyDocument, recordSessionGrant, resolveSessionId, SESSION_POLICY_SCHEMA_VERSION } from "./session-policy.js";
|
|
6
|
+
export { parseTemplateDirectiveFromText } from "./instruction-template-mapper.js";
|
|
7
|
+
export { RESPONSE_TEMPLATE_CONTRACT_VERSION, MAX_TEMPLATE_WARNING_LENGTH, truncateTemplateWarning } from "./response-template-contract.js";
|
|
8
|
+
export { allBuiltinDefinitions, getResponseTemplateDefinition, listBuiltinResponseTemplateIds } from "./response-template-registry.js";
|
|
9
|
+
export { applyResponseTemplateApplication } from "./response-template-shaping.js";
|
|
10
|
+
export { maybeSpawnTranscriptHookAfterCompletion, readAfterTaskCompletedHook, resolveWorkspaceKitCli } from "./transcript-completion-hook.js";
|
|
5
11
|
export { assertWritableKey, getConfigKeyMetadata, getConfigRegistryExport, listConfigMetadata, validatePersistedConfigDocument, validateValueForMetadata } from "./config-metadata.js";
|
|
6
12
|
export { appendConfigMutation, CONFIG_MUTATIONS_SCHEMA_VERSION, summarizeForEvidence } from "./config-mutations.js";
|
|
7
13
|
export { generateConfigReferenceDocs, runWorkspaceConfigCli } from "./config-cli.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type TemplateDirectiveParseResult = {
|
|
2
|
+
templateId: string | null;
|
|
3
|
+
warnings: string[];
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a template id from free-form instruction text (T263).
|
|
7
|
+
* Examples: "Use the COMPLETED_TASK template", "template: compact"
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseTemplateDirectiveFromText(text: string): TemplateDirectiveParseResult;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { truncateTemplateWarning } from "./response-template-contract.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a template id from free-form instruction text (T263).
|
|
4
|
+
* Examples: "Use the COMPLETED_TASK template", "template: compact"
|
|
5
|
+
*/
|
|
6
|
+
export function parseTemplateDirectiveFromText(text) {
|
|
7
|
+
const warnings = [];
|
|
8
|
+
if (!text || typeof text !== "string") {
|
|
9
|
+
return { templateId: null, warnings };
|
|
10
|
+
}
|
|
11
|
+
const s = text.trim();
|
|
12
|
+
if (!s)
|
|
13
|
+
return { templateId: null, warnings };
|
|
14
|
+
const ids = new Set();
|
|
15
|
+
const reUseThe = /\buse\s+the\s+([A-Za-z0-9_-]+)\s+template\b/gi;
|
|
16
|
+
let m;
|
|
17
|
+
while ((m = reUseThe.exec(s)) !== null) {
|
|
18
|
+
ids.add(m[1]);
|
|
19
|
+
}
|
|
20
|
+
const reTemplateEq = /\btemplate\s*[:=]\s*([A-Za-z0-9_-]+)\b/gi;
|
|
21
|
+
while ((m = reTemplateEq.exec(s)) !== null) {
|
|
22
|
+
ids.add(m[1]);
|
|
23
|
+
}
|
|
24
|
+
const reBare = /\b(?:responseTemplateId|templateId)\s+is\s+([A-Za-z0-9_-]+)\b/gi;
|
|
25
|
+
while ((m = reBare.exec(s)) !== null) {
|
|
26
|
+
ids.add(m[1]);
|
|
27
|
+
}
|
|
28
|
+
if (ids.size === 0) {
|
|
29
|
+
return { templateId: null, warnings };
|
|
30
|
+
}
|
|
31
|
+
if (ids.size > 1) {
|
|
32
|
+
warnings.push(truncateTemplateWarning("Ambiguous template directive: multiple template ids referenced; using first match."));
|
|
33
|
+
}
|
|
34
|
+
return { templateId: [...ids][0], warnings };
|
|
35
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* T203: Immutable lineage event contract (append-only store, correlation fields).
|
|
3
|
-
* @see
|
|
3
|
+
* @see .workspace-kit/tasks/state.json T192, T203
|
|
4
4
|
*/
|
|
5
5
|
export declare const LINEAGE_SCHEMA_VERSION: 1;
|
|
6
6
|
export type LineageEventType = "rec" | "dec" | "app" | "corr";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* T203: Immutable lineage event contract (append-only store, correlation fields).
|
|
3
|
-
* @see
|
|
3
|
+
* @see .workspace-kit/tasks/state.json T192, T203
|
|
4
4
|
*/
|
|
5
5
|
export const LINEAGE_SCHEMA_VERSION = 1;
|
|
6
6
|
/** Stable correlation root: ties chain to recommendation + evidence identity. */
|
package/dist/core/policy.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const POLICY_TRACE_SCHEMA_VERSION: 1;
|
|
2
|
-
export type PolicyOperationId = "cli.upgrade" | "cli.init" | "cli.config-mutate" | "policy.dynamic-sensitive" | "doc.document-project" | "doc.generate-document" | "tasks.
|
|
2
|
+
export type PolicyOperationId = "cli.upgrade" | "cli.init" | "cli.config-mutate" | "policy.dynamic-sensitive" | "doc.document-project" | "doc.generate-document" | "tasks.run-transition" | "approvals.review-item" | "improvement.generate-recommendations" | "improvement.ingest-transcripts";
|
|
3
3
|
export declare function getOperationIdForCommand(commandName: string): PolicyOperationId | undefined;
|
|
4
4
|
export declare function getExtraSensitiveModuleCommandsFromEffective(effective: Record<string, unknown>): string[];
|
|
5
5
|
/** Resolve operation id for tracing, including config-declared sensitive module commands. */
|
|
@@ -8,13 +8,24 @@ export declare function resolvePolicyOperationIdForCommand(commandName: string,
|
|
|
8
8
|
* Sensitive when mutation / write is possible. Documentation commands are exempt when dryRun is true.
|
|
9
9
|
*/
|
|
10
10
|
export declare function isSensitiveModuleCommand(commandName: string, args: Record<string, unknown>): boolean;
|
|
11
|
+
export type PolicyApprovalScope = "once" | "session";
|
|
11
12
|
export type PolicyApprovalPayload = {
|
|
12
13
|
confirmed: boolean;
|
|
13
14
|
rationale: string;
|
|
15
|
+
/** When `session`, persist approval for this operation until session id changes or grants file is cleared. */
|
|
16
|
+
scope?: PolicyApprovalScope;
|
|
14
17
|
};
|
|
15
18
|
export declare function parsePolicyApprovalFromEnv(env: NodeJS.ProcessEnv): PolicyApprovalPayload | undefined;
|
|
16
19
|
export declare function parsePolicyApproval(args: Record<string, unknown>): PolicyApprovalPayload | undefined;
|
|
17
|
-
export declare function resolveActor(
|
|
20
|
+
export declare function resolveActor(_workspacePath: string, args: Record<string, unknown>, env: NodeJS.ProcessEnv): string;
|
|
21
|
+
/**
|
|
22
|
+
* Actor precedence:
|
|
23
|
+
* 1) command args.actor
|
|
24
|
+
* 2) WORKSPACE_KIT_ACTOR
|
|
25
|
+
* 3) bounded git user.email/user.name lookup (unless WORKSPACE_KIT_ACTOR_GIT_LOOKUP=off)
|
|
26
|
+
* 4) "unknown"
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveActorWithFallback(workspacePath: string, args: Record<string, unknown>, env: NodeJS.ProcessEnv): Promise<string>;
|
|
18
29
|
export type PolicyTraceRecord = {
|
|
19
30
|
schemaVersion: number;
|
|
20
31
|
timestamp: string;
|
package/dist/core/policy.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
4
|
export const POLICY_TRACE_SCHEMA_VERSION = 1;
|
|
5
5
|
const COMMAND_TO_OPERATION = {
|
|
6
6
|
"document-project": "doc.document-project",
|
|
7
7
|
"generate-document": "doc.generate-document",
|
|
8
|
-
"import-tasks": "tasks.import-tasks",
|
|
9
|
-
"generate-tasks-md": "tasks.generate-tasks-md",
|
|
10
8
|
"run-transition": "tasks.run-transition",
|
|
11
9
|
"review-item": "approvals.review-item",
|
|
12
10
|
"generate-recommendations": "improvement.generate-recommendations",
|
|
@@ -81,39 +79,58 @@ export function parsePolicyApproval(args) {
|
|
|
81
79
|
if (!confirmed || rationale.length === 0) {
|
|
82
80
|
return undefined;
|
|
83
81
|
}
|
|
84
|
-
|
|
82
|
+
const scopeRaw = o.scope;
|
|
83
|
+
const scope = scopeRaw === "session" || scopeRaw === "once" ? scopeRaw : undefined;
|
|
84
|
+
return { confirmed, rationale, ...(scope ? { scope } : {}) };
|
|
85
85
|
}
|
|
86
|
-
export function resolveActor(
|
|
86
|
+
export function resolveActor(_workspacePath, args, env) {
|
|
87
87
|
if (typeof args.actor === "string" && args.actor.trim().length > 0) {
|
|
88
88
|
return args.actor.trim();
|
|
89
89
|
}
|
|
90
90
|
const fromEnv = env.WORKSPACE_KIT_ACTOR?.trim();
|
|
91
91
|
if (fromEnv)
|
|
92
92
|
return fromEnv;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}).trim();
|
|
99
|
-
if (email)
|
|
100
|
-
return email;
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
/* ignore */
|
|
104
|
-
}
|
|
105
|
-
try {
|
|
106
|
-
const name = execSync("git config user.name", {
|
|
93
|
+
return "unknown";
|
|
94
|
+
}
|
|
95
|
+
function runGitConfigValue(workspacePath, key, timeoutMs) {
|
|
96
|
+
return new Promise((resolve) => {
|
|
97
|
+
execFile("git", ["config", key], {
|
|
107
98
|
cwd: workspacePath,
|
|
108
99
|
encoding: "utf8",
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
timeout: timeoutMs,
|
|
101
|
+
windowsHide: true
|
|
102
|
+
}, (error, stdout) => {
|
|
103
|
+
if (error) {
|
|
104
|
+
resolve(undefined);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const trimmed = stdout.trim();
|
|
108
|
+
resolve(trimmed.length > 0 ? trimmed : undefined);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Actor precedence:
|
|
114
|
+
* 1) command args.actor
|
|
115
|
+
* 2) WORKSPACE_KIT_ACTOR
|
|
116
|
+
* 3) bounded git user.email/user.name lookup (unless WORKSPACE_KIT_ACTOR_GIT_LOOKUP=off)
|
|
117
|
+
* 4) "unknown"
|
|
118
|
+
*/
|
|
119
|
+
export async function resolveActorWithFallback(workspacePath, args, env) {
|
|
120
|
+
const explicit = resolveActor(workspacePath, args, env);
|
|
121
|
+
if (explicit !== "unknown") {
|
|
122
|
+
return explicit;
|
|
113
123
|
}
|
|
114
|
-
|
|
115
|
-
|
|
124
|
+
if (env.WORKSPACE_KIT_ACTOR_GIT_LOOKUP?.trim().toLowerCase() === "off") {
|
|
125
|
+
return "unknown";
|
|
116
126
|
}
|
|
127
|
+
const timeoutMs = 300;
|
|
128
|
+
const email = await runGitConfigValue(workspacePath, "user.email", timeoutMs);
|
|
129
|
+
if (email)
|
|
130
|
+
return email;
|
|
131
|
+
const name = await runGitConfigValue(workspacePath, "user.name", timeoutMs);
|
|
132
|
+
if (name)
|
|
133
|
+
return name;
|
|
117
134
|
return "unknown";
|
|
118
135
|
}
|
|
119
136
|
/** Policy sensitivity from built-in map plus `policy.extraSensitiveModuleCommands` on effective config. */
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Contract version for response template definitions and CLI shaping metadata. */
|
|
2
|
+
export declare const RESPONSE_TEMPLATE_CONTRACT_VERSION: 1;
|
|
3
|
+
export type ResponseTemplateEnforcementMode = "advisory" | "strict";
|
|
4
|
+
export type ResponseTemplateDefinition = {
|
|
5
|
+
id: string;
|
|
6
|
+
/** Monotonic template definition revision for compatibility notes. */
|
|
7
|
+
version: number;
|
|
8
|
+
scope: "global" | "command";
|
|
9
|
+
description: string;
|
|
10
|
+
/** Logical section keys expected in shaped command `data` (advisory hints only). */
|
|
11
|
+
expectedSections: string[];
|
|
12
|
+
};
|
|
13
|
+
/** Max length for a single advisory warning line (T265 / T266). */
|
|
14
|
+
export declare const MAX_TEMPLATE_WARNING_LENGTH = 120;
|
|
15
|
+
export declare function truncateTemplateWarning(message: string): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Contract version for response template definitions and CLI shaping metadata. */
|
|
2
|
+
export const RESPONSE_TEMPLATE_CONTRACT_VERSION = 1;
|
|
3
|
+
/** Max length for a single advisory warning line (T265 / T266). */
|
|
4
|
+
export const MAX_TEMPLATE_WARNING_LENGTH = 120;
|
|
5
|
+
export function truncateTemplateWarning(message) {
|
|
6
|
+
const t = message.trim();
|
|
7
|
+
if (t.length <= MAX_TEMPLATE_WARNING_LENGTH)
|
|
8
|
+
return t;
|
|
9
|
+
return `${t.slice(0, MAX_TEMPLATE_WARNING_LENGTH - 1)}…`;
|
|
10
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ResponseTemplateDefinition } from "./response-template-contract.js";
|
|
2
|
+
export declare function getResponseTemplateDefinition(id: string | undefined): ResponseTemplateDefinition | undefined;
|
|
3
|
+
export declare function listBuiltinResponseTemplateIds(): string[];
|
|
4
|
+
export declare function allBuiltinDefinitions(): ResponseTemplateDefinition[];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const BUILTIN = {
|
|
2
|
+
default: {
|
|
3
|
+
id: "default",
|
|
4
|
+
version: 1,
|
|
5
|
+
scope: "global",
|
|
6
|
+
description: "Passthrough with standard ok/code/message/data fields.",
|
|
7
|
+
expectedSections: ["ok", "code", "message", "data"]
|
|
8
|
+
},
|
|
9
|
+
compact: {
|
|
10
|
+
id: "compact",
|
|
11
|
+
version: 1,
|
|
12
|
+
scope: "global",
|
|
13
|
+
description: "Emphasizes top-level code and message for quick scanning.",
|
|
14
|
+
expectedSections: ["ok", "code", "message"]
|
|
15
|
+
},
|
|
16
|
+
completed_task: {
|
|
17
|
+
id: "completed_task",
|
|
18
|
+
version: 1,
|
|
19
|
+
scope: "command",
|
|
20
|
+
description: "Structured completion-style surface for task-style commands.",
|
|
21
|
+
expectedSections: ["ok", "code", "message", "data"]
|
|
22
|
+
},
|
|
23
|
+
COMPLETED_TASK: {
|
|
24
|
+
id: "COMPLETED_TASK",
|
|
25
|
+
version: 1,
|
|
26
|
+
scope: "command",
|
|
27
|
+
description: "Alias id matching plain-English directive spelling.",
|
|
28
|
+
expectedSections: ["ok", "code", "message", "data"]
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export function getResponseTemplateDefinition(id) {
|
|
32
|
+
if (!id || typeof id !== "string")
|
|
33
|
+
return undefined;
|
|
34
|
+
const trimmed = id.trim();
|
|
35
|
+
if (!trimmed)
|
|
36
|
+
return undefined;
|
|
37
|
+
return BUILTIN[trimmed] ?? BUILTIN[trimmed.toLowerCase()] ?? undefined;
|
|
38
|
+
}
|
|
39
|
+
export function listBuiltinResponseTemplateIds() {
|
|
40
|
+
return Object.keys(BUILTIN).sort((a, b) => a.localeCompare(b));
|
|
41
|
+
}
|
|
42
|
+
export function allBuiltinDefinitions() {
|
|
43
|
+
return Object.values(BUILTIN);
|
|
44
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModuleCommandResult } from "../contracts/module-contract.js";
|
|
2
|
+
/**
|
|
3
|
+
* Apply response template metadata and optional presentation hints (T262, T265).
|
|
4
|
+
* Advisory mode never flips `ok`. Strict mode fails closed on unknown template ids when a template was explicitly requested or command override is set.
|
|
5
|
+
*/
|
|
6
|
+
export declare function applyResponseTemplateApplication(commandName: string, args: Record<string, unknown>, result: ModuleCommandResult, effective: Record<string, unknown>): ModuleCommandResult;
|