odd-studio 3.7.5 → 3.7.7
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 +0 -3
- package/bin/commands/init.js +3 -41
- package/bin/commands/status.js +0 -3
- package/bin/odd-studio.js +1 -1
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/codex-plugin/hooks.json +25 -7
- package/hooks/odd-studio.sh +0 -31
- package/package.json +1 -2
- package/plugins/plugin-gates.js +104 -79
- package/scripts/command-definitions.js +7 -47
- package/scripts/hook-definitions.js +137 -0
- package/scripts/install-codex-commands.js +11 -3
- package/scripts/install-commands.js +13 -9
- package/scripts/setup-codex-plugin.js +7 -0
- package/scripts/setup-hooks.js +6 -130
- package/scripts/state-schema.js +2 -4
- package/skill/SKILL.md +50 -675
- package/skill/docs/build/build-protocol.md +1 -5
- package/skill/docs/build/confirm-protocol.md +41 -0
- package/skill/docs/build/export-protocol.md +45 -0
- package/skill/docs/chapters/chapter-10.md +2 -2
- package/skill/docs/chapters/chapter-11.md +3 -5
- package/skill/docs/chapters/chapter-12.md +2 -2
- package/skill/docs/chapters/chapter-14.md +8 -12
- package/skill/docs/runtime/build-entry.md +64 -0
- package/skill/docs/runtime/shared-commands.md +65 -0
- package/skill/docs/runtime/status-protocol.md +11 -0
- package/skill/docs/startup/startup-protocol.md +90 -0
- package/skill/odd-build/SKILL.md +6 -4
- package/skill/odd-debug/SKILL.md +3 -5
- package/skill/odd-deploy/SKILL.md +8 -3
- package/skill/odd-plan/SKILL.md +10 -3
- package/skill/odd-status/SKILL.md +3 -3
- package/skill/odd-swarm/SKILL.md +5 -4
- package/templates/.odd/state.json +1 -3
- package/templates/AGENTS.md +52 -190
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
export const HOOK_GROUPS = [
|
|
4
|
+
{
|
|
5
|
+
event: 'PreToolUse',
|
|
6
|
+
matcher: 'Agent',
|
|
7
|
+
gates: [
|
|
8
|
+
{ name: 'brief-gate', timeout: 5, status: 'ODD brief gate...' },
|
|
9
|
+
{ name: 'build-gate', timeout: 5, status: 'ODD build gate...' },
|
|
10
|
+
],
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
event: 'PreToolUse',
|
|
14
|
+
matcher: 'Write',
|
|
15
|
+
gates: [
|
|
16
|
+
{ name: 'swarm-write', timeout: 5, status: 'ODD swarm write gate...' },
|
|
17
|
+
{ name: 'verify-gate', timeout: 5, status: 'ODD verification gate...' },
|
|
18
|
+
{ name: 'confirm-gate', timeout: 5, status: 'ODD confirm gate...' },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
event: 'PreToolUse',
|
|
23
|
+
matcher: 'Edit',
|
|
24
|
+
gates: [
|
|
25
|
+
{ name: 'swarm-write', timeout: 5, status: 'ODD swarm write gate...' },
|
|
26
|
+
{ name: 'verify-gate', timeout: 5, status: 'ODD verification gate...' },
|
|
27
|
+
{ name: 'confirm-gate', timeout: 5, status: 'ODD confirm gate...' },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
event: 'UserPromptSubmit',
|
|
32
|
+
matcher: null,
|
|
33
|
+
gates: [
|
|
34
|
+
{ name: 'swarm-guard', timeout: 5, status: 'ODD swarm guard...' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
event: 'PostToolUse',
|
|
39
|
+
matcher: 'Write',
|
|
40
|
+
gates: [
|
|
41
|
+
{ name: 'plan-complete-gate', timeout: 5, status: 'ODD plan complete gate...' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
event: 'PostToolUse',
|
|
46
|
+
matcher: 'Edit',
|
|
47
|
+
gates: [
|
|
48
|
+
{ name: 'plan-complete-gate', timeout: 5, status: 'ODD plan complete gate...' },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
event: 'PostToolUse',
|
|
53
|
+
matcher: 'Bash',
|
|
54
|
+
gates: [
|
|
55
|
+
{ name: 'session-save', timeout: 10, status: 'ODD session save...' },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
event: 'PostToolUse',
|
|
60
|
+
matcher: 'mcp__odd-flow__memory_store',
|
|
61
|
+
gates: [
|
|
62
|
+
{ name: 'store-validate', timeout: 5, status: 'ODD store validate...' },
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
event: 'PostToolUse',
|
|
67
|
+
matcher: 'mcp__odd-flow__coordination_sync',
|
|
68
|
+
gates: [
|
|
69
|
+
{ name: 'sync-validate', timeout: 5, status: 'ODD sync validate...' },
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
event: 'PostToolUse',
|
|
74
|
+
matcher: 'Write',
|
|
75
|
+
gates: [
|
|
76
|
+
{ name: 'code-quality', timeout: 5, status: 'ODD code quality...' },
|
|
77
|
+
{ name: 'security-quality', timeout: 5, status: 'ODD security quality...' },
|
|
78
|
+
{ name: 'brief-quality', timeout: 5, status: 'ODD brief quality...' },
|
|
79
|
+
{ name: 'outcome-quality', timeout: 5, status: 'ODD outcome quality...' },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
event: 'PostToolUse',
|
|
84
|
+
matcher: 'Edit',
|
|
85
|
+
gates: [
|
|
86
|
+
{ name: 'code-quality', timeout: 5, status: 'ODD code quality...' },
|
|
87
|
+
{ name: 'security-quality', timeout: 5, status: 'ODD security quality...' },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
export function buildClaudeHooksConfig(hookFile) {
|
|
93
|
+
const hooks = {};
|
|
94
|
+
|
|
95
|
+
for (const { event, matcher, gates } of HOOK_GROUPS) {
|
|
96
|
+
if (!hooks[event]) hooks[event] = [];
|
|
97
|
+
|
|
98
|
+
const entry = {
|
|
99
|
+
_oddStudio: true,
|
|
100
|
+
hooks: gates.map((gate) => ({
|
|
101
|
+
type: 'command',
|
|
102
|
+
command: `.claude/hooks/${hookFile} ${gate.name}`,
|
|
103
|
+
timeout: gate.timeout,
|
|
104
|
+
statusMessage: gate.status,
|
|
105
|
+
})),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
if (matcher) entry.matcher = matcher;
|
|
109
|
+
hooks[event].push(entry);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return hooks;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function buildCodexHooksConfig(hookFile) {
|
|
116
|
+
const hooks = {};
|
|
117
|
+
|
|
118
|
+
for (const { event, matcher, gates } of HOOK_GROUPS) {
|
|
119
|
+
if (!hooks[event]) hooks[event] = [];
|
|
120
|
+
|
|
121
|
+
const entry = {
|
|
122
|
+
hooks: gates.map((gate) => ({
|
|
123
|
+
type: 'command',
|
|
124
|
+
command: `./hooks/${hookFile} ${gate.name}`,
|
|
125
|
+
})),
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
if (matcher) entry.matcher = matcher;
|
|
129
|
+
hooks[event].push(entry);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return { hooks };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function countHookCommands() {
|
|
136
|
+
return HOOK_GROUPS.reduce((sum, group) => sum + group.gates.length, 0);
|
|
137
|
+
}
|
|
@@ -29,10 +29,10 @@ function buildMainCommand(cmd) {
|
|
|
29
29
|
'',
|
|
30
30
|
`# ${CODEX_COMMAND_PREFIX}${cmd.name}`,
|
|
31
31
|
'',
|
|
32
|
-
'You are now operating as the ODD Studio coach.',
|
|
32
|
+
'You are now operating as the ODD Studio startup coach.',
|
|
33
33
|
'',
|
|
34
34
|
'Read this file now:',
|
|
35
|
-
`- \`${CODEX_ODD_ROOT}SKILL.md\` — the
|
|
35
|
+
`- \`${CODEX_ODD_ROOT}SKILL.md\` — the ODD Studio startup coach`,
|
|
36
36
|
'',
|
|
37
37
|
'Then execute the startup state check exactly as documented.',
|
|
38
38
|
'',
|
|
@@ -53,5 +53,13 @@ function buildSubcommand(cmd) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function rewriteBody(body) {
|
|
56
|
-
return body
|
|
56
|
+
return body
|
|
57
|
+
.replace(/`\.opencode\/odd\/odd-build\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-build/SKILL.md`')
|
|
58
|
+
.replace(/`\.opencode\/odd\/odd-debug\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-debug/SKILL.md`')
|
|
59
|
+
.replace(/`\.opencode\/odd\/odd-plan\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-plan/SKILL.md`')
|
|
60
|
+
.replace(/`\.opencode\/odd\/odd-swarm\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-swarm/SKILL.md`')
|
|
61
|
+
.replace(/`\.opencode\/odd\/odd-status\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-status/SKILL.md`')
|
|
62
|
+
.replace(/`\.opencode\/odd\/odd-deploy\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-deploy/SKILL.md`')
|
|
63
|
+
.replace(/`\.opencode\/odd\/odd-sync\/SKILL\.md`/g, '`plugins/odd-studio/skills/odd-sync/SKILL.md`')
|
|
64
|
+
.replace(/`\.opencode\/odd\//g, `\`${CODEX_ODD_ROOT}`);
|
|
57
65
|
}
|
|
@@ -47,13 +47,7 @@ export default async function installCommands(packageRoot, targetDir, options =
|
|
|
47
47
|
const skillSource = path.join(packageRoot, 'skill');
|
|
48
48
|
await fs.copy(skillSource, oddKnowledge, { overwrite: true });
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
const mainSkill = path.join(oddKnowledge, 'SKILL.md');
|
|
52
|
-
if (fs.existsSync(mainSkill)) {
|
|
53
|
-
let content = await fs.readFile(mainSkill, 'utf8');
|
|
54
|
-
content = content.replace(/~\/\.claude\/skills\/odd\//g, '.opencode/odd/');
|
|
55
|
-
await fs.writeFile(mainSkill, content);
|
|
56
|
-
}
|
|
50
|
+
await rewriteSkillPaths(oddKnowledge);
|
|
57
51
|
|
|
58
52
|
// Generate the /odd command that loads the main skill
|
|
59
53
|
const oddCmd = [
|
|
@@ -63,10 +57,10 @@ export default async function installCommands(packageRoot, targetDir, options =
|
|
|
63
57
|
'',
|
|
64
58
|
'# /odd',
|
|
65
59
|
'',
|
|
66
|
-
'You are now operating as the ODD Studio coach.',
|
|
60
|
+
'You are now operating as the ODD Studio startup coach.',
|
|
67
61
|
'',
|
|
68
62
|
'Read this file now:',
|
|
69
|
-
'- `.opencode/odd/SKILL.md` — the
|
|
63
|
+
'- `.opencode/odd/SKILL.md` — the ODD Studio startup coach',
|
|
70
64
|
'',
|
|
71
65
|
'Then execute the startup state check exactly as documented.',
|
|
72
66
|
'',
|
|
@@ -76,3 +70,13 @@ export default async function installCommands(packageRoot, targetDir, options =
|
|
|
76
70
|
|
|
77
71
|
return { destination: OC_COMMANDS, commandCount: COMMANDS.length };
|
|
78
72
|
}
|
|
73
|
+
|
|
74
|
+
async function rewriteSkillPaths(rootDir) {
|
|
75
|
+
const skillFiles = await fs.glob(path.join(rootDir, '**', 'SKILL.md'));
|
|
76
|
+
for (const filePath of skillFiles) {
|
|
77
|
+
let content = await fs.readFile(filePath, 'utf8');
|
|
78
|
+
content = content.replace(/~\/\.claude\/skills\/odd\//g, '.opencode/odd/');
|
|
79
|
+
content = content.replace(/\.claude\/skills\/odd\//g, '.opencode/odd/');
|
|
80
|
+
await fs.writeFile(filePath, content);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ODD_HOOK_FILE,
|
|
8
8
|
} from './assets.js';
|
|
9
9
|
import installCodexCommands from './install-codex-commands.js';
|
|
10
|
+
import { buildCodexHooksConfig } from './hook-definitions.js';
|
|
10
11
|
|
|
11
12
|
const PLUGIN_RELATIVE_PATH = `./plugins/${CODEX_PLUGIN_NAME}`;
|
|
12
13
|
const MARKETPLACE_ENTRY = {
|
|
@@ -36,6 +37,7 @@ export default async function setupCodexPlugin(packageRoot, targetDir) {
|
|
|
36
37
|
await installCodexSkills(skillSource, pluginDest);
|
|
37
38
|
await installCodexCommands(pluginDest);
|
|
38
39
|
await installCodexHook(hookSource, pluginDest);
|
|
40
|
+
await installCodexHooksConfig(pluginDest);
|
|
39
41
|
const marketplaceUpdated = await updateMarketplace(targetDir);
|
|
40
42
|
|
|
41
43
|
return { destination: pluginDest, marketplaceUpdated };
|
|
@@ -80,6 +82,11 @@ async function installCodexHook(hookSource, pluginDest) {
|
|
|
80
82
|
await fs.chmod(hookDest, 0o755);
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
async function installCodexHooksConfig(pluginDest) {
|
|
86
|
+
const hooksPath = path.join(pluginDest, 'hooks.json');
|
|
87
|
+
await fs.writeJson(hooksPath, buildCodexHooksConfig(ODD_HOOK_FILE), { spaces: 2 });
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
async function updateMarketplace(targetDir) {
|
|
84
91
|
const marketplacePath = path.join(targetDir, '.agents', 'plugins', 'marketplace.json');
|
|
85
92
|
await fs.ensureDir(path.dirname(marketplacePath));
|
package/scripts/setup-hooks.js
CHANGED
|
@@ -2,117 +2,7 @@
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { ODD_HOOK_FILE as HOOK_FILE } from './assets.js';
|
|
5
|
-
|
|
6
|
-
// All ODD Studio gates, grouped by event + matcher.
|
|
7
|
-
// Each entry becomes one hooks[] item in settings.json pointing to:
|
|
8
|
-
// odd-studio.sh <gate-name>
|
|
9
|
-
//
|
|
10
|
-
// Two-marker system (swarm-write gate):
|
|
11
|
-
// 1. .odd/.odd-flow-swarm-active — created by *build, 24h TTL (session marker)
|
|
12
|
-
// 2. .odd/.odd-flow-agent-token — created by Task agents, 120s TTL (write token)
|
|
13
|
-
//
|
|
14
|
-
// The orchestrator (main conversation) can read files and coordinate,
|
|
15
|
-
// but CANNOT write source code. Only Task agents can write source code,
|
|
16
|
-
// and only after creating the agent token. This prevents the LLM from
|
|
17
|
-
// bypassing swarm coordination by editing files directly from the main
|
|
18
|
-
// conversation.
|
|
19
|
-
const GATES = [
|
|
20
|
-
// ── PreToolUse ──────────────────────────────────────────────────────────
|
|
21
|
-
{
|
|
22
|
-
event: 'PreToolUse',
|
|
23
|
-
matcher: 'Agent',
|
|
24
|
-
gates: [
|
|
25
|
-
{ name: 'brief-gate', timeout: 5, status: 'ODD brief gate...' },
|
|
26
|
-
{ name: 'build-gate', timeout: 5, status: 'ODD build gate...' },
|
|
27
|
-
],
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
event: 'PreToolUse',
|
|
31
|
-
matcher: 'Write',
|
|
32
|
-
gates: [
|
|
33
|
-
{ name: 'swarm-write', timeout: 5, status: 'ODD swarm write gate...' },
|
|
34
|
-
{ name: 'verify-gate', timeout: 5, status: 'ODD verification gate...' },
|
|
35
|
-
{ name: 'confirm-gate', timeout: 5, status: 'ODD confirm gate...' },
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
event: 'PreToolUse',
|
|
40
|
-
matcher: 'Edit',
|
|
41
|
-
gates: [
|
|
42
|
-
{ name: 'swarm-write', timeout: 5, status: 'ODD swarm write gate...' },
|
|
43
|
-
{ name: 'verify-gate', timeout: 5, status: 'ODD verification gate...' },
|
|
44
|
-
{ name: 'confirm-gate', timeout: 5, status: 'ODD confirm gate...' },
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
event: 'PreToolUse',
|
|
49
|
-
matcher: 'Bash',
|
|
50
|
-
gates: [
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
// ── UserPromptSubmit ────────────────────────────────────────────────────
|
|
54
|
-
{
|
|
55
|
-
event: 'UserPromptSubmit',
|
|
56
|
-
matcher: null,
|
|
57
|
-
gates: [
|
|
58
|
-
{ name: 'swarm-guard', timeout: 5, status: 'ODD swarm guard...' },
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
// ── PostToolUse ─────────────────────────────────────────────────────────
|
|
62
|
-
{
|
|
63
|
-
event: 'PostToolUse',
|
|
64
|
-
matcher: 'Write',
|
|
65
|
-
gates: [
|
|
66
|
-
{ name: 'plan-complete-gate', timeout: 5, status: 'ODD plan complete gate...' },
|
|
67
|
-
],
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
event: 'PostToolUse',
|
|
71
|
-
matcher: 'Edit',
|
|
72
|
-
gates: [
|
|
73
|
-
{ name: 'plan-complete-gate', timeout: 5, status: 'ODD plan complete gate...' },
|
|
74
|
-
],
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
event: 'PostToolUse',
|
|
78
|
-
matcher: 'Bash',
|
|
79
|
-
gates: [
|
|
80
|
-
{ name: 'session-save', timeout: 10, status: 'ODD session save...' },
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
event: 'PostToolUse',
|
|
85
|
-
matcher: 'mcp__odd-flow__memory_store',
|
|
86
|
-
gates: [
|
|
87
|
-
{ name: 'store-validate', timeout: 5, status: 'ODD store validate...' },
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
event: 'PostToolUse',
|
|
92
|
-
matcher: 'mcp__odd-flow__coordination_sync',
|
|
93
|
-
gates: [
|
|
94
|
-
{ name: 'sync-validate', timeout: 5, status: 'ODD sync validate...' },
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
event: 'PostToolUse',
|
|
99
|
-
matcher: 'Write',
|
|
100
|
-
gates: [
|
|
101
|
-
{ name: 'code-quality', timeout: 5, status: 'ODD code quality...' },
|
|
102
|
-
{ name: 'security-quality', timeout: 5, status: 'ODD security quality...' },
|
|
103
|
-
{ name: 'brief-quality', timeout: 5, status: 'ODD brief quality...' },
|
|
104
|
-
{ name: 'outcome-quality', timeout: 5, status: 'ODD outcome quality...' },
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
event: 'PostToolUse',
|
|
109
|
-
matcher: 'Edit',
|
|
110
|
-
gates: [
|
|
111
|
-
{ name: 'code-quality', timeout: 5, status: 'ODD code quality...' },
|
|
112
|
-
{ name: 'security-quality', timeout: 5, status: 'ODD security quality...' },
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
];
|
|
5
|
+
import { HOOK_GROUPS, buildClaudeHooksConfig, countHookCommands } from './hook-definitions.js';
|
|
116
6
|
|
|
117
7
|
export default async function setupHooks(packageRoot, targetDir, options = {}) {
|
|
118
8
|
const hookSource = path.join(packageRoot, 'hooks', HOOK_FILE);
|
|
@@ -149,33 +39,19 @@ export default async function setupHooks(packageRoot, targetDir, options = {}) {
|
|
|
149
39
|
}
|
|
150
40
|
|
|
151
41
|
// Step 4: Register all gates
|
|
152
|
-
|
|
153
|
-
|
|
42
|
+
const oddHooks = buildClaudeHooksConfig(HOOK_FILE);
|
|
43
|
+
for (const event of Object.keys(oddHooks)) {
|
|
154
44
|
if (!settings.hooks[event]) settings.hooks[event] = [];
|
|
155
|
-
|
|
156
|
-
const entry = {
|
|
157
|
-
_oddStudio: true,
|
|
158
|
-
hooks: gates.map((gate) => ({
|
|
159
|
-
type: 'command',
|
|
160
|
-
command: `.claude/hooks/${HOOK_FILE} ${gate.name}`,
|
|
161
|
-
timeout: gate.timeout,
|
|
162
|
-
statusMessage: gate.status,
|
|
163
|
-
})),
|
|
164
|
-
};
|
|
165
|
-
if (matcher) entry.matcher = matcher;
|
|
166
|
-
|
|
167
|
-
settings.hooks[event].push(entry);
|
|
45
|
+
settings.hooks[event].push(...oddHooks[event]);
|
|
168
46
|
}
|
|
169
47
|
|
|
170
48
|
// Step 5: Write project-local settings
|
|
171
49
|
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
172
50
|
|
|
173
51
|
// Count total gate registrations
|
|
174
|
-
const totalGates = GATES.reduce((sum, g) => sum + g.gates.length, 0);
|
|
175
|
-
|
|
176
52
|
return {
|
|
177
53
|
hookFile: HOOK_FILE,
|
|
178
|
-
hookCount:
|
|
179
|
-
registrations:
|
|
54
|
+
hookCount: countHookCommands(),
|
|
55
|
+
registrations: HOOK_GROUPS.length,
|
|
180
56
|
};
|
|
181
57
|
}
|
package/scripts/state-schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
export const STATE_VERSION = '2.
|
|
3
|
+
export const STATE_VERSION = '2.2.0';
|
|
4
4
|
|
|
5
5
|
export const STATE_DEFAULTS = {
|
|
6
6
|
version: STATE_VERSION,
|
|
@@ -24,6 +24,7 @@ export const STATE_DEFAULTS = {
|
|
|
24
24
|
sessionBriefCount: 0,
|
|
25
25
|
briefConfirmed: false,
|
|
26
26
|
verificationConfirmed: false,
|
|
27
|
+
debugSession: false,
|
|
27
28
|
swarmActive: false,
|
|
28
29
|
buildPhase: null,
|
|
29
30
|
currentBuildPhase: null,
|
|
@@ -32,9 +33,6 @@ export const STATE_DEFAULTS = {
|
|
|
32
33
|
debugTarget: null,
|
|
33
34
|
debugSummary: null,
|
|
34
35
|
debugStartedAt: null,
|
|
35
|
-
checkpointStatus: 'unknown',
|
|
36
|
-
lastCheckpointAt: null,
|
|
37
|
-
checkpointFindings: 0,
|
|
38
36
|
securityBaselineVersion: '2026-04-12',
|
|
39
37
|
notes: '',
|
|
40
38
|
};
|