@planu/cli 1.11.0 → 1.12.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/dist/config/license-plans.json +27 -2
- package/dist/engine/api-compat/compatibility-checker.d.ts +4 -0
- package/dist/engine/api-compat/compatibility-checker.d.ts.map +1 -0
- package/dist/engine/api-compat/compatibility-checker.js +118 -0
- package/dist/engine/api-compat/compatibility-checker.js.map +1 -0
- package/dist/engine/checkpoint/checkpoint-manager.d.ts +22 -0
- package/dist/engine/checkpoint/checkpoint-manager.d.ts.map +1 -0
- package/dist/engine/checkpoint/checkpoint-manager.js +76 -0
- package/dist/engine/checkpoint/checkpoint-manager.js.map +1 -0
- package/dist/engine/checkpoint/policy-engine.d.ts +10 -0
- package/dist/engine/checkpoint/policy-engine.d.ts.map +1 -0
- package/dist/engine/checkpoint/policy-engine.js +87 -0
- package/dist/engine/checkpoint/policy-engine.js.map +1 -0
- package/dist/engine/compliance/auto-remediator.d.ts +9 -0
- package/dist/engine/compliance/auto-remediator.d.ts.map +1 -0
- package/dist/engine/compliance/auto-remediator.js +118 -0
- package/dist/engine/compliance/auto-remediator.js.map +1 -0
- package/dist/engine/context-profile/profile-catalog.d.ts +5 -0
- package/dist/engine/context-profile/profile-catalog.d.ts.map +1 -0
- package/dist/engine/context-profile/profile-catalog.js +145 -0
- package/dist/engine/context-profile/profile-catalog.js.map +1 -0
- package/dist/engine/critical-path/path-analyzer.d.ts +3 -0
- package/dist/engine/critical-path/path-analyzer.d.ts.map +1 -0
- package/dist/engine/critical-path/path-analyzer.js +145 -0
- package/dist/engine/critical-path/path-analyzer.js.map +1 -0
- package/dist/engine/drift/violation-resolver.d.ts +9 -0
- package/dist/engine/drift/violation-resolver.d.ts.map +1 -0
- package/dist/engine/drift/violation-resolver.js +128 -0
- package/dist/engine/drift/violation-resolver.js.map +1 -0
- package/dist/engine/ears/criterion-scorer.d.ts +7 -0
- package/dist/engine/ears/criterion-scorer.d.ts.map +1 -0
- package/dist/engine/ears/criterion-scorer.js +87 -0
- package/dist/engine/ears/criterion-scorer.js.map +1 -0
- package/dist/engine/ears/pattern-matcher.d.ts +5 -0
- package/dist/engine/ears/pattern-matcher.d.ts.map +1 -0
- package/dist/engine/ears/pattern-matcher.js +48 -0
- package/dist/engine/ears/pattern-matcher.js.map +1 -0
- package/dist/engine/ears/rewriter.d.ts +7 -0
- package/dist/engine/ears/rewriter.d.ts.map +1 -0
- package/dist/engine/ears/rewriter.js +45 -0
- package/dist/engine/ears/rewriter.js.map +1 -0
- package/dist/engine/ears/spec-linter.d.ts +7 -0
- package/dist/engine/ears/spec-linter.d.ts.map +1 -0
- package/dist/engine/ears/spec-linter.js +127 -0
- package/dist/engine/ears/spec-linter.js.map +1 -0
- package/dist/engine/health/auto-fixer.d.ts +7 -0
- package/dist/engine/health/auto-fixer.d.ts.map +1 -0
- package/dist/engine/health/auto-fixer.js +130 -0
- package/dist/engine/health/auto-fixer.js.map +1 -0
- package/dist/engine/mcp-catalog/catalog-advisor.d.ts +3 -0
- package/dist/engine/mcp-catalog/catalog-advisor.d.ts.map +1 -0
- package/dist/engine/mcp-catalog/catalog-advisor.js +180 -0
- package/dist/engine/mcp-catalog/catalog-advisor.js.map +1 -0
- package/dist/engine/similar-problems/similarity-finder.d.ts +3 -0
- package/dist/engine/similar-problems/similarity-finder.d.ts.map +1 -0
- package/dist/engine/similar-problems/similarity-finder.js +144 -0
- package/dist/engine/similar-problems/similarity-finder.js.map +1 -0
- package/dist/engine/sync/asana-puller.d.ts +9 -0
- package/dist/engine/sync/asana-puller.d.ts.map +1 -0
- package/dist/engine/sync/asana-puller.js +91 -0
- package/dist/engine/sync/asana-puller.js.map +1 -0
- package/dist/engine/sync/conflict-resolver.d.ts +17 -0
- package/dist/engine/sync/conflict-resolver.d.ts.map +1 -0
- package/dist/engine/sync/conflict-resolver.js +58 -0
- package/dist/engine/sync/conflict-resolver.js.map +1 -0
- package/dist/engine/sync/monday-puller.d.ts +9 -0
- package/dist/engine/sync/monday-puller.d.ts.map +1 -0
- package/dist/engine/sync/monday-puller.js +110 -0
- package/dist/engine/sync/monday-puller.js.map +1 -0
- package/dist/engine/sync/notion-puller.d.ts +15 -0
- package/dist/engine/sync/notion-puller.d.ts.map +1 -0
- package/dist/engine/sync/notion-puller.js +101 -0
- package/dist/engine/sync/notion-puller.js.map +1 -0
- package/dist/engine/verifier/code-scanner.d.ts +8 -0
- package/dist/engine/verifier/code-scanner.d.ts.map +1 -0
- package/dist/engine/verifier/code-scanner.js +73 -0
- package/dist/engine/verifier/code-scanner.js.map +1 -0
- package/dist/engine/verifier/compliance-scorer.d.ts +17 -0
- package/dist/engine/verifier/compliance-scorer.d.ts.map +1 -0
- package/dist/engine/verifier/compliance-scorer.js +131 -0
- package/dist/engine/verifier/compliance-scorer.js.map +1 -0
- package/dist/engine/verifier/criterion-matcher.d.ts +15 -0
- package/dist/engine/verifier/criterion-matcher.d.ts.map +1 -0
- package/dist/engine/verifier/criterion-matcher.js +210 -0
- package/dist/engine/verifier/criterion-matcher.js.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/compliance-score-store.d.ts +16 -0
- package/dist/storage/compliance-score-store.d.ts.map +1 -0
- package/dist/storage/compliance-score-store.js +30 -0
- package/dist/storage/compliance-score-store.js.map +1 -0
- package/dist/storage/context-profile-store.d.ts +14 -0
- package/dist/storage/context-profile-store.d.ts.map +1 -0
- package/dist/storage/context-profile-store.js +34 -0
- package/dist/storage/context-profile-store.js.map +1 -0
- package/dist/storage/workflow-checkpoint-store.d.ts +16 -0
- package/dist/storage/workflow-checkpoint-store.d.ts.map +1 -0
- package/dist/storage/workflow-checkpoint-store.js +71 -0
- package/dist/storage/workflow-checkpoint-store.js.map +1 -0
- package/dist/tools/checkpoint/approve-checkpoint-handler.d.ts +3 -0
- package/dist/tools/checkpoint/approve-checkpoint-handler.d.ts.map +1 -0
- package/dist/tools/checkpoint/approve-checkpoint-handler.js +32 -0
- package/dist/tools/checkpoint/approve-checkpoint-handler.js.map +1 -0
- package/dist/tools/checkpoint/configure-policy-handler.d.ts +3 -0
- package/dist/tools/checkpoint/configure-policy-handler.d.ts.map +1 -0
- package/dist/tools/checkpoint/configure-policy-handler.js +60 -0
- package/dist/tools/checkpoint/configure-policy-handler.js.map +1 -0
- package/dist/tools/checkpoint/list-checkpoints-handler.d.ts +3 -0
- package/dist/tools/checkpoint/list-checkpoints-handler.d.ts.map +1 -0
- package/dist/tools/checkpoint/list-checkpoints-handler.js +25 -0
- package/dist/tools/checkpoint/list-checkpoints-handler.js.map +1 -0
- package/dist/tools/checkpoint/reject-checkpoint-handler.d.ts +3 -0
- package/dist/tools/checkpoint/reject-checkpoint-handler.d.ts.map +1 -0
- package/dist/tools/checkpoint/reject-checkpoint-handler.js +32 -0
- package/dist/tools/checkpoint/reject-checkpoint-handler.js.map +1 -0
- package/dist/tools/checkpoint/require-checkpoint-handler.d.ts +3 -0
- package/dist/tools/checkpoint/require-checkpoint-handler.d.ts.map +1 -0
- package/dist/tools/checkpoint/require-checkpoint-handler.js +44 -0
- package/dist/tools/checkpoint/require-checkpoint-handler.js.map +1 -0
- package/dist/tools/pull-sync-handler.d.ts +25 -0
- package/dist/tools/pull-sync-handler.d.ts.map +1 -0
- package/dist/tools/pull-sync-handler.js +161 -0
- package/dist/tools/pull-sync-handler.js.map +1 -0
- package/dist/tools/register-auto-remediation.d.ts +3 -0
- package/dist/tools/register-auto-remediation.d.ts.map +1 -0
- package/dist/tools/register-auto-remediation.js +174 -0
- package/dist/tools/register-auto-remediation.js.map +1 -0
- package/dist/tools/register-checkpoints.d.ts +3 -0
- package/dist/tools/register-checkpoints.d.ts.map +1 -0
- package/dist/tools/register-checkpoints.js +134 -0
- package/dist/tools/register-checkpoints.js.map +1 -0
- package/dist/tools/register-context-profile.d.ts +3 -0
- package/dist/tools/register-context-profile.d.ts.map +1 -0
- package/dist/tools/register-context-profile.js +106 -0
- package/dist/tools/register-context-profile.js.map +1 -0
- package/dist/tools/register-ears.d.ts +3 -0
- package/dist/tools/register-ears.d.ts.map +1 -0
- package/dist/tools/register-ears.js +148 -0
- package/dist/tools/register-ears.js.map +1 -0
- package/dist/tools/register-enterprise-compliance.js +1 -1
- package/dist/tools/register-enterprise-compliance.js.map +1 -1
- package/dist/tools/register-pull-sync.d.ts +3 -0
- package/dist/tools/register-pull-sync.d.ts.map +1 -0
- package/dist/tools/register-pull-sync.js +71 -0
- package/dist/tools/register-pull-sync.js.map +1 -0
- package/dist/tools/register-spec405-tools.d.ts +7 -0
- package/dist/tools/register-spec405-tools.d.ts.map +1 -0
- package/dist/tools/register-spec405-tools.js +194 -0
- package/dist/tools/register-spec405-tools.js.map +1 -0
- package/dist/tools/register-verifier.d.ts +3 -0
- package/dist/tools/register-verifier.d.ts.map +1 -0
- package/dist/tools/register-verifier.js +141 -0
- package/dist/tools/register-verifier.js.map +1 -0
- package/dist/types/analysis.d.ts +98 -0
- package/dist/types/analysis.d.ts.map +1 -1
- package/dist/types/context-profile.d.ts +22 -0
- package/dist/types/context-profile.d.ts.map +1 -0
- package/dist/types/context-profile.js +2 -0
- package/dist/types/context-profile.js.map +1 -0
- package/dist/types/ears.d.ts +34 -0
- package/dist/types/ears.d.ts.map +1 -0
- package/dist/types/ears.js +3 -0
- package/dist/types/ears.js.map +1 -0
- package/dist/types/health.d.ts +40 -0
- package/dist/types/health.d.ts.map +1 -0
- package/dist/types/health.js +3 -0
- package/dist/types/health.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/notion-asana-monday.d.ts +38 -0
- package/dist/types/notion-asana-monday.d.ts.map +1 -1
- package/dist/types/workflow-checkpoint.d.ts +66 -0
- package/dist/types/workflow-checkpoint.d.ts.map +1 -0
- package/dist/types/workflow-checkpoint.js +4 -0
- package/dist/types/workflow-checkpoint.js.map +1 -0
- package/package.json +1 -1
- package/src/config/license-plans.json +27 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ActiveProfile, WorkPhase } from '../types/context-profile.js';
|
|
2
|
+
/**
|
|
3
|
+
* Persist the active work phase for a project.
|
|
4
|
+
*/
|
|
5
|
+
export declare function setActiveProfile(projectPath: string, phase: WorkPhase): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Retrieve the active profile for a project, or null if none is set.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getActiveProfile(projectPath: string): Promise<ActiveProfile | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Remove the active profile for a project.
|
|
12
|
+
*/
|
|
13
|
+
export declare function clearActiveProfile(projectPath: string): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=context-profile-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-profile-store.d.ts","sourceRoot":"","sources":["../../src/storage/context-profile-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAO5E;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3F;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAIzF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readJson, writeJson, hashProjectPath } from './base-store.js';
|
|
2
|
+
function profileFile(projectId) {
|
|
3
|
+
return `data/projects/${projectId}/context-profile.json`;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Persist the active work phase for a project.
|
|
7
|
+
*/
|
|
8
|
+
export async function setActiveProfile(projectPath, phase) {
|
|
9
|
+
const projectId = hashProjectPath(projectPath);
|
|
10
|
+
const file = profileFile(projectId);
|
|
11
|
+
const profile = {
|
|
12
|
+
projectPath,
|
|
13
|
+
phase,
|
|
14
|
+
activatedAt: new Date().toISOString(),
|
|
15
|
+
};
|
|
16
|
+
await writeJson(file, profile);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Retrieve the active profile for a project, or null if none is set.
|
|
20
|
+
*/
|
|
21
|
+
export async function getActiveProfile(projectPath) {
|
|
22
|
+
const projectId = hashProjectPath(projectPath);
|
|
23
|
+
const file = profileFile(projectId);
|
|
24
|
+
return readJson(file, null);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Remove the active profile for a project.
|
|
28
|
+
*/
|
|
29
|
+
export async function clearActiveProfile(projectPath) {
|
|
30
|
+
const projectId = hashProjectPath(projectPath);
|
|
31
|
+
const file = profileFile(projectId);
|
|
32
|
+
await writeJson(file, null);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=context-profile-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-profile-store.js","sourceRoot":"","sources":["../../src/storage/context-profile-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvE,SAAS,WAAW,CAAC,SAAiB;IACpC,OAAO,iBAAiB,SAAS,uBAAuB,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB,EAAE,KAAgB;IAC1E,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,OAAO,GAAkB;QAC7B,WAAW;QACX,KAAK;QACL,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IACF,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACxD,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAuB,IAAI,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB;IAC1D,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkflowCheckpoint } from '../types/index.js';
|
|
2
|
+
/** Persist a new checkpoint and return it with its generated ID. */
|
|
3
|
+
export declare function createWorkflowCheckpoint(projectPath: string, checkpoint: Omit<WorkflowCheckpoint, 'id'>): Promise<WorkflowCheckpoint>;
|
|
4
|
+
/** Resolve a checkpoint (approve or reject). Returns the updated checkpoint. */
|
|
5
|
+
export declare function resolveWorkflowCheckpoint(projectPath: string, checkpointId: string, resolution: {
|
|
6
|
+
status: 'approved' | 'rejected';
|
|
7
|
+
resolvedBy: string;
|
|
8
|
+
rejectionReason?: string;
|
|
9
|
+
}): Promise<WorkflowCheckpoint>;
|
|
10
|
+
/** Return all pending checkpoints for a project, optionally filtered by role. */
|
|
11
|
+
export declare function getPendingWorkflowCheckpoints(projectPath: string, role?: string): Promise<WorkflowCheckpoint[]>;
|
|
12
|
+
/** Return a single checkpoint by ID, or null if not found. */
|
|
13
|
+
export declare function getWorkflowCheckpoint(projectPath: string, checkpointId: string): Promise<WorkflowCheckpoint | null>;
|
|
14
|
+
/** Return all checkpoints for a given spec. */
|
|
15
|
+
export declare function getCheckpointsForSpec(projectPath: string, specId: string): Promise<WorkflowCheckpoint[]>;
|
|
16
|
+
//# sourceMappingURL=workflow-checkpoint-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-checkpoint-store.d.ts","sourceRoot":"","sources":["../../src/storage/workflow-checkpoint-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAsB5D,oEAAoE;AACpE,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,GACzC,OAAO,CAAC,kBAAkB,CAAC,CAO7B;AAED,gFAAgF;AAChF,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE;IACV,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,OAAO,CAAC,kBAAkB,CAAC,CAsB7B;AAED,iFAAiF;AACjF,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAM/B;AAED,8DAA8D;AAC9D,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAIpC;AAED,+CAA+C;AAC/C,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAI/B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// storage/workflow-checkpoint-store.ts — Workflow checkpoint persistence (SPEC-411)
|
|
2
|
+
// Layout: data/projects/{hash}/workflow-checkpoints.json
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import { readJson, writeJson, projectDataDir, hashProjectPath } from './base-store.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Helpers
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function storeFilePath(projectId) {
|
|
9
|
+
return `${projectDataDir(projectId)}/workflow-checkpoints.json`;
|
|
10
|
+
}
|
|
11
|
+
async function loadAll(projectId) {
|
|
12
|
+
return readJson(storeFilePath(projectId), []);
|
|
13
|
+
}
|
|
14
|
+
async function saveAll(projectId, checkpoints) {
|
|
15
|
+
await writeJson(storeFilePath(projectId), checkpoints);
|
|
16
|
+
}
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// CRUD operations
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/** Persist a new checkpoint and return it with its generated ID. */
|
|
21
|
+
export async function createWorkflowCheckpoint(projectPath, checkpoint) {
|
|
22
|
+
const projectId = hashProjectPath(projectPath);
|
|
23
|
+
const all = await loadAll(projectId);
|
|
24
|
+
const record = { id: randomUUID(), ...checkpoint };
|
|
25
|
+
all.push(record);
|
|
26
|
+
await saveAll(projectId, all);
|
|
27
|
+
return record;
|
|
28
|
+
}
|
|
29
|
+
/** Resolve a checkpoint (approve or reject). Returns the updated checkpoint. */
|
|
30
|
+
export async function resolveWorkflowCheckpoint(projectPath, checkpointId, resolution) {
|
|
31
|
+
const projectId = hashProjectPath(projectPath);
|
|
32
|
+
const all = await loadAll(projectId);
|
|
33
|
+
const idx = all.findIndex((c) => c.id === checkpointId);
|
|
34
|
+
if (idx === -1) {
|
|
35
|
+
throw new Error(`[Planu] Checkpoint not found: ${checkpointId}`);
|
|
36
|
+
}
|
|
37
|
+
const existing = all[idx];
|
|
38
|
+
/* v8 ignore next 3 */
|
|
39
|
+
if (!existing) {
|
|
40
|
+
throw new Error(`[Planu] Checkpoint not found: ${checkpointId}`);
|
|
41
|
+
}
|
|
42
|
+
const updated = {
|
|
43
|
+
...existing,
|
|
44
|
+
status: resolution.status,
|
|
45
|
+
resolvedBy: resolution.resolvedBy,
|
|
46
|
+
resolvedAt: new Date().toISOString(),
|
|
47
|
+
rejectionReason: resolution.rejectionReason,
|
|
48
|
+
};
|
|
49
|
+
all[idx] = updated;
|
|
50
|
+
await saveAll(projectId, all);
|
|
51
|
+
return updated;
|
|
52
|
+
}
|
|
53
|
+
/** Return all pending checkpoints for a project, optionally filtered by role. */
|
|
54
|
+
export async function getPendingWorkflowCheckpoints(projectPath, role) {
|
|
55
|
+
const projectId = hashProjectPath(projectPath);
|
|
56
|
+
const all = await loadAll(projectId);
|
|
57
|
+
return all.filter((c) => c.status === 'pending' && (role === undefined || c.requiredRole === role));
|
|
58
|
+
}
|
|
59
|
+
/** Return a single checkpoint by ID, or null if not found. */
|
|
60
|
+
export async function getWorkflowCheckpoint(projectPath, checkpointId) {
|
|
61
|
+
const projectId = hashProjectPath(projectPath);
|
|
62
|
+
const all = await loadAll(projectId);
|
|
63
|
+
return all.find((c) => c.id === checkpointId) ?? null;
|
|
64
|
+
}
|
|
65
|
+
/** Return all checkpoints for a given spec. */
|
|
66
|
+
export async function getCheckpointsForSpec(projectPath, specId) {
|
|
67
|
+
const projectId = hashProjectPath(projectPath);
|
|
68
|
+
const all = await loadAll(projectId);
|
|
69
|
+
return all.filter((c) => c.specId === specId);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=workflow-checkpoint-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-checkpoint-store.js","sourceRoot":"","sources":["../../src/storage/workflow-checkpoint-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve-checkpoint-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/checkpoint/approve-checkpoint-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG/E,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CA8B/F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// tools/checkpoint/approve-checkpoint-handler.ts — approve_checkpoint handler (SPEC-411)
|
|
2
|
+
import { approveCheckpoint } from '../../engine/checkpoint/checkpoint-manager.js';
|
|
3
|
+
export async function handleApproveCheckpoint(args) {
|
|
4
|
+
const { projectPath, checkpointId, approvedBy = 'anonymous' } = args;
|
|
5
|
+
let result;
|
|
6
|
+
try {
|
|
7
|
+
result = await approveCheckpoint(projectPath, checkpointId, approvedBy);
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11
|
+
return {
|
|
12
|
+
content: [{ type: 'text', text: `Error approving checkpoint: ${message}` }],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const { checkpoint } = result;
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: [
|
|
21
|
+
`Checkpoint ${checkpointId} approved by ${approvedBy}.`,
|
|
22
|
+
`Spec: ${checkpoint.specId}`,
|
|
23
|
+
`Transition unblocked: ${checkpoint.blockingTransition}`,
|
|
24
|
+
'',
|
|
25
|
+
'Next step: run update_status to apply the transition now that the checkpoint is approved.',
|
|
26
|
+
].join('\n'),
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
structuredContent: { checkpoint, transitionApplied: result.transitionApplied },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=approve-checkpoint-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approve-checkpoint-handler.js","sourceRoot":"","sources":["../../../src/tools/checkpoint/approve-checkpoint-handler.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAGzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAElF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAA4B;IACxE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC;IAErE,IAAI,MAAqD,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,OAAO,EAAE,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAE9B,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,cAAc,YAAY,gBAAgB,UAAU,GAAG;oBACvD,SAAS,UAAU,CAAC,MAAM,EAAE;oBAC5B,yBAAyB,UAAU,CAAC,kBAAkB,EAAE;oBACxD,EAAE;oBACF,2FAA2F;iBAC5F,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;QACD,iBAAiB,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE;KAC/E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-policy-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/checkpoint/configure-policy-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,UAAU,EACV,8BAA8B,EAE/B,MAAM,sBAAsB,CAAC;AAO9B,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,8BAA8B,GACnC,OAAO,CAAC,UAAU,CAAC,CA4DrB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// tools/checkpoint/configure-policy-handler.ts — configure_checkpoint_policy handler (SPEC-411)
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { POLICY_PRESETS, loadCheckpointConfig, saveCheckpointConfig, } from '../../engine/checkpoint/policy-engine.js';
|
|
4
|
+
export async function handleConfigureCheckpointPolicy(args) {
|
|
5
|
+
const { projectPath, preset, policies } = args;
|
|
6
|
+
if (preset === undefined && (policies === undefined || policies.length === 0)) {
|
|
7
|
+
return {
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: 'text',
|
|
11
|
+
text: 'Error: provide either a preset (strict/balanced/relaxed) or a custom policies array.',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
let activePolicies;
|
|
17
|
+
let activePreset;
|
|
18
|
+
if (preset !== undefined) {
|
|
19
|
+
const presetDef = POLICY_PRESETS[preset];
|
|
20
|
+
if (presetDef === undefined) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: 'text', text: `Error: unknown preset "${preset}".` }],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
activePolicies = presetDef.policies.map((p) => ({ id: randomUUID(), ...p }));
|
|
26
|
+
activePreset = preset;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
activePolicies = (policies ?? []).map((p) => ({
|
|
30
|
+
id: randomUUID(),
|
|
31
|
+
transition: p.transition,
|
|
32
|
+
requiredRole: p.requiredRole,
|
|
33
|
+
description: p.description,
|
|
34
|
+
autoApproveAfterHours: p.autoApproveAfterHours,
|
|
35
|
+
}));
|
|
36
|
+
activePreset = 'custom';
|
|
37
|
+
}
|
|
38
|
+
const config = await loadCheckpointConfig(projectPath);
|
|
39
|
+
config.policies = activePolicies;
|
|
40
|
+
config.activePreset = activePreset;
|
|
41
|
+
await saveCheckpointConfig(projectPath, config);
|
|
42
|
+
const policyLines = activePolicies
|
|
43
|
+
.map((p) => ` • ${p.transition} — requires ${p.requiredRole}: ${p.description}`)
|
|
44
|
+
.join('\n');
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text',
|
|
49
|
+
text: [
|
|
50
|
+
`Checkpoint policy configured (preset: ${activePreset}).`,
|
|
51
|
+
'',
|
|
52
|
+
'Active policies:',
|
|
53
|
+
policyLines,
|
|
54
|
+
].join('\n'),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
structuredContent: { activePreset, policies: activePolicies },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=configure-policy-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-policy-handler.js","sourceRoot":"","sources":["../../../src/tools/checkpoint/configure-policy-handler.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzC,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,0CAA0C,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,IAAoC;IAEpC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE/C,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,sFAAsF;iBAC7F;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,cAAkC,CAAC;IACvC,IAAI,YAA0D,CAAC;IAE/D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,0BAA0B,MAAM,IAAI,EAAE,CAAC;aACxE,CAAC;QACJ,CAAC;QACD,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7E,YAAY,GAAG,MAAM,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,cAAc,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5C,EAAE,EAAE,UAAU,EAAE;YAChB,UAAU,EAAE,CAAC,CAAC,UAA4C;YAC1D,YAAY,EAAE,CAAC,CAAC,YAAgD;YAChE,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,qBAAqB,EAAE,CAAC,CAAC,qBAAqB;SAC/C,CAAC,CAAC,CAAC;QACJ,YAAY,GAAG,QAAQ,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,CAAC,QAAQ,GAAG,cAAc,CAAC;IACjC,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,MAAM,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAEhD,MAAM,WAAW,GAAG,cAAc;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,UAAU,eAAe,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;SAChF,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,yCAAyC,YAAY,IAAI;oBACzD,EAAE;oBACF,kBAAkB;oBAClB,WAAW;iBACZ,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;QACD,iBAAiB,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE;KAC9D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-checkpoints-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/checkpoint/list-checkpoints-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAGpF,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,UAAU,CAAC,CA4BrB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// tools/checkpoint/list-checkpoints-handler.ts — list_pending_checkpoints handler (SPEC-411)
|
|
2
|
+
import { getPendingWorkflowCheckpoints } from '../../storage/workflow-checkpoint-store.js';
|
|
3
|
+
export async function handleListPendingCheckpoints(args) {
|
|
4
|
+
const { projectPath, role } = args;
|
|
5
|
+
const pending = await getPendingWorkflowCheckpoints(projectPath, role);
|
|
6
|
+
if (pending.length === 0) {
|
|
7
|
+
const roleNote = role !== undefined ? ` for role "${role}"` : '';
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: 'text', text: `No pending checkpoints${roleNote}.` }],
|
|
10
|
+
structuredContent: { checkpoints: [] },
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const lines = pending.map((c) => `• [${c.id.slice(0, 8)}] ${c.specId} — ${c.blockingTransition} — needs ${c.requiredRole} (requested by ${c.requestedBy} at ${c.requestedAt})`);
|
|
14
|
+
const roleNote = role !== undefined ? ` (filtered by role: ${role})` : '';
|
|
15
|
+
return {
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: [`Pending checkpoints${roleNote}:`, '', ...lines].join('\n'),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
structuredContent: { checkpoints: pending },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=list-checkpoints-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-checkpoints-handler.js","sourceRoot":"","sources":["../../../src/tools/checkpoint/list-checkpoints-handler.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAG7F,OAAO,EAAE,6BAA6B,EAAE,MAAM,4CAA4C,CAAC;AAE3F,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,IAAiC;IAEjC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IAEnC,MAAM,OAAO,GAAG,MAAM,6BAA6B,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAEvE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,QAAQ,GAAG,EAAE,CAAC;YACvE,iBAAiB,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;SACvC,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CACvB,CAAC,CAAC,EAAE,EAAE,CACJ,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,kBAAkB,YAAY,CAAC,CAAC,YAAY,kBAAkB,CAAC,CAAC,WAAW,OAAO,CAAC,CAAC,WAAW,GAAG,CAChJ,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,uBAAuB,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,CAAC,sBAAsB,QAAQ,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;aACnE;SACF;QACD,iBAAiB,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE;KAC5C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-checkpoint-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/checkpoint/reject-checkpoint-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6B7F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// tools/checkpoint/reject-checkpoint-handler.ts — reject_checkpoint handler (SPEC-411)
|
|
2
|
+
import { rejectCheckpoint } from '../../engine/checkpoint/checkpoint-manager.js';
|
|
3
|
+
export async function handleRejectCheckpoint(args) {
|
|
4
|
+
const { projectPath, checkpointId, rejectedBy = 'anonymous', reason } = args;
|
|
5
|
+
let checkpoint;
|
|
6
|
+
try {
|
|
7
|
+
checkpoint = await rejectCheckpoint(projectPath, checkpointId, rejectedBy, reason);
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11
|
+
return {
|
|
12
|
+
content: [{ type: 'text', text: `Error rejecting checkpoint: ${message}` }],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: [
|
|
20
|
+
`Checkpoint ${checkpointId} rejected by ${rejectedBy}.`,
|
|
21
|
+
`Spec: ${checkpoint.specId}`,
|
|
22
|
+
`Blocked transition: ${checkpoint.blockingTransition}`,
|
|
23
|
+
`Reason: ${reason}`,
|
|
24
|
+
'',
|
|
25
|
+
'The spec remains in its current status. Address the feedback and create a new checkpoint request when ready.',
|
|
26
|
+
].join('\n'),
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
structuredContent: { checkpoint },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=reject-checkpoint-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject-checkpoint-handler.js","sourceRoot":"","sources":["../../../src/tools/checkpoint/reject-checkpoint-handler.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAGvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAEjF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAA2B;IACtE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,GAAG,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAE7E,IAAI,UAAwD,CAAC;IAC7D,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,gBAAgB,CAAC,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,OAAO,EAAE,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,cAAc,YAAY,gBAAgB,UAAU,GAAG;oBACvD,SAAS,UAAU,CAAC,MAAM,EAAE;oBAC5B,uBAAuB,UAAU,CAAC,kBAAkB,EAAE;oBACtD,WAAW,MAAM,EAAE;oBACnB,EAAE;oBACF,8GAA8G;iBAC/G,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;QACD,iBAAiB,EAAE,EAAE,UAAU,EAAE;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-checkpoint-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/checkpoint/require-checkpoint-handler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI/E,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6C/F"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// tools/checkpoint/require-checkpoint-handler.ts — require_checkpoint handler (SPEC-411)
|
|
2
|
+
import { loadCheckpointConfig } from '../../engine/checkpoint/policy-engine.js';
|
|
3
|
+
import { requestCheckpoint } from '../../engine/checkpoint/checkpoint-manager.js';
|
|
4
|
+
export async function handleRequireCheckpoint(args) {
|
|
5
|
+
const { projectPath, specId, transition, requestedBy = 'system' } = args;
|
|
6
|
+
const config = await loadCheckpointConfig(projectPath);
|
|
7
|
+
const policy = config.policies.find((p) => p.transition === transition);
|
|
8
|
+
if (policy === undefined) {
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: 'text',
|
|
13
|
+
text: [
|
|
14
|
+
`No policy found for transition "${transition}".`,
|
|
15
|
+
'Configure one first with configure_checkpoint_policy.',
|
|
16
|
+
].join('\n'),
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const checkpoint = await requestCheckpoint(projectPath, specId, policy, requestedBy);
|
|
22
|
+
const autoApproveNote = checkpoint.autoApproveAt !== undefined
|
|
23
|
+
? `\nAuto-approve scheduled at: ${checkpoint.autoApproveAt}`
|
|
24
|
+
: '';
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: [
|
|
30
|
+
`Checkpoint created for ${specId} (${transition}).`,
|
|
31
|
+
`Checkpoint ID: ${checkpoint.id}`,
|
|
32
|
+
`Required approver role: ${policy.requiredRole}`,
|
|
33
|
+
`Reason: ${policy.description}`,
|
|
34
|
+
autoApproveNote,
|
|
35
|
+
'',
|
|
36
|
+
`To approve: approve_checkpoint { projectPath, checkpointId: "${checkpoint.id}", approvedBy: "<your-id>" }`,
|
|
37
|
+
`To reject: reject_checkpoint { projectPath, checkpointId: "${checkpoint.id}", rejectedBy: "<your-id>", reason: "<reason>" }`,
|
|
38
|
+
].join('\n'),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
structuredContent: { checkpoint },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=require-checkpoint-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-checkpoint-handler.js","sourceRoot":"","sources":["../../../src/tools/checkpoint/require-checkpoint-handler.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAGzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAElF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAA4B;IACxE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;IAEzE,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IAExE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,mCAAmC,UAAU,IAAI;wBACjD,uDAAuD;qBACxD,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAErF,MAAM,eAAe,GACnB,UAAU,CAAC,aAAa,KAAK,SAAS;QACpC,CAAC,CAAC,gCAAgC,UAAU,CAAC,aAAa,EAAE;QAC5D,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE;oBACJ,0BAA0B,MAAM,KAAK,UAAU,IAAI;oBACnD,kBAAkB,UAAU,CAAC,EAAE,EAAE;oBACjC,2BAA2B,MAAM,CAAC,YAAY,EAAE;oBAChD,WAAW,MAAM,CAAC,WAAW,EAAE;oBAC/B,eAAe;oBACf,EAAE;oBACF,gEAAgE,UAAU,CAAC,EAAE,8BAA8B;oBAC3G,gEAAgE,UAAU,CAAC,EAAE,kDAAkD;iBAChI,CAAC,IAAI,CAAC,IAAI,CAAC;aACb;SACF;QACD,iBAAiB,EAAE,EAAE,UAAU,EAAE;KAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ToolResult, PmConflictStrategy } from '../types/index.js';
|
|
2
|
+
export interface PullFromNotionInput {
|
|
3
|
+
projectPath: string;
|
|
4
|
+
conflictStrategy?: PmConflictStrategy;
|
|
5
|
+
createMissing?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface PullFromAsanaInput {
|
|
8
|
+
projectPath: string;
|
|
9
|
+
conflictStrategy?: PmConflictStrategy;
|
|
10
|
+
createMissing?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface PullFromMondayInput {
|
|
13
|
+
projectPath: string;
|
|
14
|
+
conflictStrategy?: PmConflictStrategy;
|
|
15
|
+
createMissing?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface SyncAllIntegrationsInput {
|
|
18
|
+
projectPath: string;
|
|
19
|
+
conflictStrategy?: PmConflictStrategy;
|
|
20
|
+
}
|
|
21
|
+
export declare function handlePullFromNotion(input: PullFromNotionInput): Promise<ToolResult>;
|
|
22
|
+
export declare function handlePullFromAsana(input: PullFromAsanaInput): Promise<ToolResult>;
|
|
23
|
+
export declare function handlePullFromMonday(input: PullFromMondayInput): Promise<ToolResult>;
|
|
24
|
+
export declare function handleSyncAllIntegrations(input: SyncAllIntegrationsInput): Promise<ToolResult>;
|
|
25
|
+
//# sourceMappingURL=pull-sync-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull-sync-handler.d.ts","sourceRoot":"","sources":["../../src/tools/pull-sync-handler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAGV,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAQ3B,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;CACvC;AAMD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAa1F;AAMD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAaxF;AAMD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAa1F;AAMD,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAyDrB"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { pullFromNotion } from '../engine/sync/notion-puller.js';
|
|
2
|
+
import { pullFromAsana } from '../engine/sync/asana-puller.js';
|
|
3
|
+
import { pullFromMonday } from '../engine/sync/monday-puller.js';
|
|
4
|
+
import { getNotionConfig } from '../storage/notion-config-store.js';
|
|
5
|
+
import { getAsanaConfig } from '../storage/asana-config-store.js';
|
|
6
|
+
import { getMondayConfig } from '../storage/monday-config-store.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// pull_from_notion
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export async function handlePullFromNotion(input) {
|
|
11
|
+
const strategy = input.conflictStrategy ?? 'spec-wins';
|
|
12
|
+
try {
|
|
13
|
+
const result = await pullFromNotion(input.projectPath, strategy);
|
|
14
|
+
return { content: [{ type: 'text', text: formatPullResult(result) }] };
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
18
|
+
return {
|
|
19
|
+
content: [{ type: 'text', text: `pull_from_notion failed: ${message}` }],
|
|
20
|
+
isError: true,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// pull_from_asana
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
export async function handlePullFromAsana(input) {
|
|
28
|
+
const strategy = input.conflictStrategy ?? 'spec-wins';
|
|
29
|
+
try {
|
|
30
|
+
const result = await pullFromAsana(input.projectPath, strategy);
|
|
31
|
+
return { content: [{ type: 'text', text: formatPullResult(result) }] };
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: 'text', text: `pull_from_asana failed: ${message}` }],
|
|
37
|
+
isError: true,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// pull_from_monday
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
export async function handlePullFromMonday(input) {
|
|
45
|
+
const strategy = input.conflictStrategy ?? 'spec-wins';
|
|
46
|
+
try {
|
|
47
|
+
const result = await pullFromMonday(input.projectPath, strategy);
|
|
48
|
+
return { content: [{ type: 'text', text: formatPullResult(result) }] };
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: 'text', text: `pull_from_monday failed: ${message}` }],
|
|
54
|
+
isError: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// sync_all_integrations
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
export async function handleSyncAllIntegrations(input) {
|
|
62
|
+
const strategy = input.conflictStrategy ?? 'spec-wins';
|
|
63
|
+
const summary = {
|
|
64
|
+
totalPulled: 0,
|
|
65
|
+
totalConflicts: 0,
|
|
66
|
+
conflictsResolved: 0,
|
|
67
|
+
};
|
|
68
|
+
const [notionConfig, asanaConfig, mondayConfig] = await Promise.all([
|
|
69
|
+
getNotionConfig(input.projectPath),
|
|
70
|
+
getAsanaConfig(input.projectPath),
|
|
71
|
+
getMondayConfig(input.projectPath),
|
|
72
|
+
]);
|
|
73
|
+
if (notionConfig !== null) {
|
|
74
|
+
try {
|
|
75
|
+
const result = await pullFromNotion(input.projectPath, strategy);
|
|
76
|
+
summary.notion = result;
|
|
77
|
+
summary.totalPulled += result.pulled.length;
|
|
78
|
+
summary.totalConflicts += result.conflicts.length;
|
|
79
|
+
summary.conflictsResolved += result.conflicts.filter((c) => c.resolution !== 'pending-manual').length;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Non-fatal: continue with other integrations
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (asanaConfig !== null) {
|
|
86
|
+
try {
|
|
87
|
+
const result = await pullFromAsana(input.projectPath, strategy);
|
|
88
|
+
summary.asana = result;
|
|
89
|
+
summary.totalPulled += result.pulled.length;
|
|
90
|
+
summary.totalConflicts += result.conflicts.length;
|
|
91
|
+
summary.conflictsResolved += result.conflicts.filter((c) => c.resolution !== 'pending-manual').length;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Non-fatal: continue with other integrations
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (mondayConfig !== null) {
|
|
98
|
+
try {
|
|
99
|
+
const result = await pullFromMonday(input.projectPath, strategy);
|
|
100
|
+
summary.monday = result;
|
|
101
|
+
summary.totalPulled += result.pulled.length;
|
|
102
|
+
summary.totalConflicts += result.conflicts.length;
|
|
103
|
+
summary.conflictsResolved += result.conflicts.filter((c) => c.resolution !== 'pending-manual').length;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Non-fatal: continue with other integrations
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { content: [{ type: 'text', text: formatSyncAllResult(summary) }] };
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Formatting helpers
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
function formatPullResult(result) {
|
|
115
|
+
const lines = [
|
|
116
|
+
`**${capitalize(result.integration)} Pull Sync** — ${result.executedAt.slice(0, 19)}`,
|
|
117
|
+
'',
|
|
118
|
+
`- Updates pulled: ${result.pulled.length}`,
|
|
119
|
+
`- Conflicts detected: ${result.conflicts.length}`,
|
|
120
|
+
`- New specs created: ${result.newSpecsCreated.length}`,
|
|
121
|
+
];
|
|
122
|
+
if (result.pulled.length > 0) {
|
|
123
|
+
lines.push('', '**Applied Updates:**');
|
|
124
|
+
for (const u of result.pulled) {
|
|
125
|
+
lines.push(`- [${u.specId}] ${u.field}: \`${u.oldValue}\` → \`${u.newValue}\``);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (result.conflicts.length > 0) {
|
|
129
|
+
lines.push('', '**Conflicts:**');
|
|
130
|
+
for (const c of result.conflicts) {
|
|
131
|
+
lines.push(`- [${c.specId}] ${c.field}: planu=\`${c.planuValue}\` vs external=\`${c.externalValue}\` → ${c.resolution}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
function formatSyncAllResult(result) {
|
|
137
|
+
const active = [
|
|
138
|
+
result.notion !== undefined ? 'Notion' : null,
|
|
139
|
+
result.asana !== undefined ? 'Asana' : null,
|
|
140
|
+
result.monday !== undefined ? 'Monday.com' : null,
|
|
141
|
+
]
|
|
142
|
+
.filter(Boolean)
|
|
143
|
+
.join(', ');
|
|
144
|
+
const lines = [
|
|
145
|
+
'**Sync All Integrations**',
|
|
146
|
+
'',
|
|
147
|
+
`Integrations synced: ${active !== '' ? active : 'none configured'}`,
|
|
148
|
+
'',
|
|
149
|
+
`| Metric | Value |`,
|
|
150
|
+
`|--------|-------|`,
|
|
151
|
+
`| Total pulled | ${result.totalPulled} |`,
|
|
152
|
+
`| Total conflicts | ${result.totalConflicts} |`,
|
|
153
|
+
`| Conflicts resolved | ${result.conflictsResolved} |`,
|
|
154
|
+
`| Pending manual | ${result.totalConflicts - result.conflictsResolved} |`,
|
|
155
|
+
];
|
|
156
|
+
return lines.join('\n');
|
|
157
|
+
}
|
|
158
|
+
function capitalize(s) {
|
|
159
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=pull-sync-handler.js.map
|