@adhamalkhaja/seyola-runtime 0.12.2 → 0.13.1

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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * seyola-runtime verify-write-count — generic Phase-6 self-check.
3
+ *
4
+ * The I-008 fix codified as a runtime check. Skills like
5
+ * /sales-infrastructure write exactly 3 (or 5 for sales_email) files in
6
+ * their Phase 6. If duplicate writes happen, I-008 reproduces and
7
+ * downstream skills get confused.
8
+ *
9
+ * This command counts files written to specific paths within a recent
10
+ * time window + verifies the count matches expected. Returns structured
11
+ * verdict.
12
+ *
13
+ * Usage:
14
+ * seyola-runtime verify-write-count --expected 3 --workspace .
15
+ * --paths outreach/reply-playbook.md,outreach/lead-tracker.md,outreach/booking-flow-setup.md
16
+ * --since 2026-05-24T10:00:00Z
17
+ *
18
+ * Returns: {verdict, actual_count, expected_count, files_found, duplicates_detected}
19
+ *
20
+ * Note: this command operates on filesystem state, not session history.
21
+ * If a skill writes a file twice in the SAME session, only the latest
22
+ * version exists on disk — so this won't directly catch "wrote it twice."
23
+ * But it WILL catch "wrote a file that shouldn't exist" or "didn't write
24
+ * a file that should." For genuine duplicate-write detection, the skill
25
+ * must log its Write tool calls separately and pass --log <path>.
26
+ */
27
+ export interface VerifyWriteCountInputs {
28
+ workspacePath: string;
29
+ expected: number;
30
+ paths?: string[];
31
+ since?: string;
32
+ json?: boolean;
33
+ }
34
+ export interface VerifyWriteCountResult {
35
+ exitCode: number;
36
+ expected_count: number;
37
+ actual_count: number;
38
+ verdict: "pass" | "fail";
39
+ files_found: Array<{
40
+ path: string;
41
+ modified: string;
42
+ size_bytes: number;
43
+ }>;
44
+ files_missing: string[];
45
+ unexpected_files: string[];
46
+ duration_ms: number;
47
+ }
48
+ export declare function runVerifyWriteCount(inputs: VerifyWriteCountInputs): Promise<VerifyWriteCountResult>;
49
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verify-write-count/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuEzG"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * seyola-runtime verify-write-count — generic Phase-6 self-check.
3
+ *
4
+ * The I-008 fix codified as a runtime check. Skills like
5
+ * /sales-infrastructure write exactly 3 (or 5 for sales_email) files in
6
+ * their Phase 6. If duplicate writes happen, I-008 reproduces and
7
+ * downstream skills get confused.
8
+ *
9
+ * This command counts files written to specific paths within a recent
10
+ * time window + verifies the count matches expected. Returns structured
11
+ * verdict.
12
+ *
13
+ * Usage:
14
+ * seyola-runtime verify-write-count --expected 3 --workspace .
15
+ * --paths outreach/reply-playbook.md,outreach/lead-tracker.md,outreach/booking-flow-setup.md
16
+ * --since 2026-05-24T10:00:00Z
17
+ *
18
+ * Returns: {verdict, actual_count, expected_count, files_found, duplicates_detected}
19
+ *
20
+ * Note: this command operates on filesystem state, not session history.
21
+ * If a skill writes a file twice in the SAME session, only the latest
22
+ * version exists on disk — so this won't directly catch "wrote it twice."
23
+ * But it WILL catch "wrote a file that shouldn't exist" or "didn't write
24
+ * a file that should." For genuine duplicate-write detection, the skill
25
+ * must log its Write tool calls separately and pass --log <path>.
26
+ */
27
+ import { existsSync, statSync } from "node:fs";
28
+ import { join, resolve } from "node:path";
29
+ export async function runVerifyWriteCount(inputs) {
30
+ const start = Date.now();
31
+ const workspace = resolve(inputs.workspacePath);
32
+ const expectedPaths = inputs.paths ?? [];
33
+ let sinceDate = null;
34
+ if (inputs.since) {
35
+ sinceDate = new Date(inputs.since);
36
+ if (isNaN(sinceDate.getTime())) {
37
+ const result = {
38
+ exitCode: 2,
39
+ expected_count: inputs.expected,
40
+ actual_count: 0,
41
+ verdict: "fail",
42
+ files_found: [],
43
+ files_missing: [],
44
+ unexpected_files: [],
45
+ duration_ms: Date.now() - start,
46
+ };
47
+ if (inputs.json)
48
+ console.log(JSON.stringify({ ...result, error: "Invalid --since date" }, null, 2));
49
+ else
50
+ console.error(`verify-write-count: invalid --since date '${inputs.since}'`);
51
+ return result;
52
+ }
53
+ }
54
+ const filesFound = [];
55
+ const filesMissing = [];
56
+ for (const relPath of expectedPaths) {
57
+ const absPath = join(workspace, relPath);
58
+ if (!existsSync(absPath)) {
59
+ filesMissing.push(relPath);
60
+ continue;
61
+ }
62
+ const stat = statSync(absPath);
63
+ if (sinceDate && stat.mtime < sinceDate) {
64
+ // File exists but was written before the --since cutoff. Treat as missing for this check.
65
+ filesMissing.push(`${relPath} (modified before --since cutoff)`);
66
+ continue;
67
+ }
68
+ filesFound.push({
69
+ path: relPath,
70
+ modified: stat.mtime.toISOString(),
71
+ size_bytes: stat.size,
72
+ });
73
+ }
74
+ const actualCount = filesFound.length;
75
+ const verdict = actualCount === inputs.expected && filesMissing.length === 0 ? "pass" : "fail";
76
+ const result = {
77
+ exitCode: verdict === "pass" ? 0 : 1,
78
+ expected_count: inputs.expected,
79
+ actual_count: actualCount,
80
+ verdict,
81
+ files_found: filesFound,
82
+ files_missing: filesMissing,
83
+ unexpected_files: [], // could extend to scan for files that shouldn't exist
84
+ duration_ms: Date.now() - start,
85
+ };
86
+ if (inputs.json) {
87
+ console.log(JSON.stringify(result, null, 2));
88
+ }
89
+ else {
90
+ console.error(`verify-write-count: ${verdict} (${actualCount}/${inputs.expected}` +
91
+ (filesMissing.length > 0 ? `, missing: ${filesMissing.join(", ")}` : "") +
92
+ `)`);
93
+ }
94
+ return result;
95
+ }
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verify-write-count/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhamalkhaja/seyola-runtime",
3
- "version": "0.12.2",
3
+ "version": "0.13.1",
4
4
  "description": "Local CLI runtime for the Seyola business operating system. Reads contracts from a Seyola pack and executes them against a runtime backend (claude-code-local).",
5
5
  "keywords": [
6
6
  "seyola",