@antoneeo/mkt-agentic-sdlc-skill 0.2.1 → 0.3.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/scripts/init.js CHANGED
@@ -1,147 +1,214 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { execSync } = require('child_process');
6
- const { SKILL_SOURCE, CLIENTS, clientDetected, loadTemplates, templateFor } = require('./lib');
7
-
8
- const cwd = process.cwd();
9
-
10
- // 1. Directory layout (canonical mkt_docs structure)
11
- const directories = [
12
- 'mkt_docs',
13
- 'mkt_docs/vision',
14
- 'mkt_docs/research',
15
- 'mkt_docs/strategy',
16
- 'mkt_docs/tactics',
17
- 'mkt_docs/deliverables',
18
- 'mkt_docs/audit',
19
- 'mkt_docs/spikes',
20
- ].map((d) => path.join(cwd, d));
21
-
22
- // 2. Project protocol (thin pointer — the operating contract is the skill).
23
- // Deliberately short: duplicating the skill's rules here made them drift.
24
- const protocolContent = `# Marketing Agentic SDLC — Project Protocol (pointer)
25
-
26
- This project follows the Marketing Agentic SDLC Evidence-First process. The full
27
- operating contract is the \`mkt-agentic-sdlc\` skill (installed in your agent's
28
- skills directory); this file is only the minimal always-on pointer.
29
-
30
- ## Rule Zero — Triage every request
31
- - E1 Quick: single question or asset feedback (positioning opinion, copy critique). Answer directly; numbers still need a source.
32
- - E2 Campaign: single-campaign or single-channel plan. Light path: mini-brief + targeted research + campaign document.
33
- - E3 Full Plan: complete marketing plan. Full SOSTAC workflow via the skill: Discovery -> Research -> Situation -> Objectives -> Strategy -> Tactics -> Action -> Control -> Packaging.
34
- - Research Spike: time-boxed market question; outcome in \`mkt_docs/spikes/RESEARCH_[topic].md\`.
35
- - When in doubt, pick the higher level. Declare the chosen level when starting.
36
-
37
- ## The three non-negotiables
38
- 1. Evidence ledger: every market number carries an [EV-nn] reference (FACT / BENCHMARK / ASSUMPTION). No invented numbers, ever.
39
- 2. Ask only what the user owns: facts come from the user, analysis comes from research. Never ask the user to do the analysis.
40
- 3. Internal consistency: budget sums, funnel math and the objective->tactic->KPI chain are validated mechanically before delivery.
41
-
42
- ## Where things live
43
- - Vision (gate for E3): \`mkt_docs/vision/MKT_VISION.md\` — \`Status: DRAFT\` informs, \`Status: APPROVED\` binds.
44
- - Evidence: \`mkt_docs/research/evidence_ledger.md\` (the single source for every number).
45
- - Strategy artifacts: \`mkt_docs/strategy/\`; tactical artifacts: \`mkt_docs/tactics/\`; final deliverables: \`mkt_docs/deliverables/\`.
46
- - Must-reads: \`mkt_docs/README.md\`; full generated manifest: \`mkt_docs/INDEX.md\`.
47
- - If devPNT is available for this project, its M-VISION / plans / governed artifacts take over (Hybrid mode — see the skill).
48
-
49
- ## Closure gate
50
- Deliverables ship only after \`python <skill_dir>/scripts/mkt_check.py check\` is
51
- CLEAN (where the validator is adopted) and the CMO review passed.
52
-
53
- If the mkt-agentic-sdlc skill is not available in this client, ask the user to install it:
54
- \`npm i -g @antoneeo/mkt-agentic-sdlc-skill\` (the skill installs automatically;
55
- if npm blocks scripts, run \`npx mkt-sdlc-install-skill\`).
56
- `;
57
-
58
- console.log('🚀 Initializing Marketing Agentic SDLC workflow...');
59
-
60
- // 3. Load templates from the single source (skill's templates.md)
61
- let sections;
62
- try {
63
- sections = loadTemplates();
64
- } catch (err) {
65
- console.error(`❌ Cannot load templates: ${err.message}`);
66
- process.exit(1);
67
- }
68
-
69
- let seedFiles;
70
- try {
71
- seedFiles = [
72
- ['mkt_docs/README.md', templateFor(sections, 'mkt_docs/README.md')],
73
- ['mkt_docs/vision/MKT_VISION.md', templateFor(sections, 'MKT_VISION.md')],
74
- ['mkt_docs/vision/principles.md', templateFor(sections, 'principles.md')],
75
- ['mkt_docs/research/evidence_ledger.md', templateFor(sections, 'evidence_ledger.md')],
76
- // NOTE: INDEX.md is NOT seeded — it is generated by `mkt_check.py index`
77
- // and would immediately fail validate.
78
- ];
79
- } catch (err) {
80
- console.error(`❌ ${err.message}`);
81
- process.exit(1);
82
- }
83
-
84
- // 4. Create directories
85
- directories.forEach((dir) => {
86
- if (!fs.existsSync(dir)) {
87
- fs.mkdirSync(dir, { recursive: true });
88
- console.log(`📁 Created directory: ${path.relative(cwd, dir)}`);
89
- }
90
- });
91
-
92
- // 5. Write seed files (never overwrite)
93
- const writeIfNotExists = (relPath, content, description) => {
94
- const filePath = path.join(cwd, relPath);
95
- if (!fs.existsSync(filePath)) {
96
- fs.writeFileSync(filePath, content, 'utf8');
97
- console.log(`📄 Created file: ${relPath}${description ? ` (${description})` : ''}`);
98
- return true;
99
- }
100
- console.log(`⏭️ Skipped: ${relPath} already exists.`);
101
- return false;
102
- };
103
-
104
- seedFiles.forEach(([relPath, content]) => writeIfNotExists(relPath, content));
105
-
106
- // 6. Client discovery and protocol pointers
107
- console.log('\n--- Environment Analysis ---');
108
-
109
- const protocolFiles = {
110
- claude: 'CLAUDE.md',
111
- gemini: 'GEMINI.md',
112
- codex: 'AGENTS.md',
113
- antigravity: 'AGENTS.md', // Antigravity CLI reads AGENTS.md; single protocolContent reused.
114
- };
115
-
116
- for (const client of CLIENTS) {
117
- if (clientDetected(client)) {
118
- console.log(`✅ ${client.label} detected.`);
119
- writeIfNotExists(protocolFiles[client.key], protocolContent, `${client.label} protocol pointer`);
120
- }
121
- }
122
-
123
- // Cursor/Windsurf (always recommended)
124
- writeIfNotExists('.cursorrules', protocolContent, 'Cursor/Windsurf rules');
125
-
126
- // 7. Generate mkt_docs/INDEX.md so the very first `validate` is already clean.
127
- // The manifest is generated, never seeded: delegate to the validator if Python is available.
128
- const validator = path.join(SKILL_SOURCE, 'scripts', 'mkt_check.py');
129
- let indexed = false;
130
- for (const py of ['python', 'python3', 'py']) {
131
- try {
132
- execSync(`${py} "${validator}" index --root "${cwd}"`, { stdio: 'ignore' });
133
- console.log('📇 Generated mkt_docs/INDEX.md (document manifest).');
134
- indexed = true;
135
- break;
136
- } catch (e) { /* try the next interpreter */ }
137
- }
138
- if (!indexed) {
139
- console.log('ℹ️ Python not found: generate the manifest later with '
140
- + '"python <skill_dir>/scripts/mkt_check.py index" (validate reports it until then).');
141
- }
142
-
143
- console.log('\n✅ Setup completed successfully!');
144
- console.log('💡 Next steps:');
145
- console.log(' 1. Make sure the mkt-agentic-sdlc skill is installed (mkt-sdlc-install-skill).');
146
- console.log(' 2. Restart/open the project in your AI client so it reads the protocol pointer.');
147
- console.log(' 3. Start an E3 engagement: the skill runs Discovery (its questions) before anything else.');
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+ const { SKILL_SOURCE, CLIENTS, clientDetected, skillTarget, loadTemplates, templateFor } = require('./lib');
7
+
8
+ // Sibling lenses of the same family: one shared core, one `ai_docs/` tree, a different
9
+ // fidelity discipline each. Keyed by the installed skill directory name.
10
+ const SIBLING_LENSES = {
11
+ 'kb-agentic': 'knowledge',
12
+ 'agentic-sdlc': 'code',
13
+ };
14
+
15
+ const cwd = process.cwd();
16
+
17
+ // 1. Directory layout (canonical mkt_docs structure)
18
+ const directories = [
19
+ 'mkt_docs',
20
+ 'mkt_docs/vision',
21
+ 'mkt_docs/research',
22
+ 'mkt_docs/strategy',
23
+ 'mkt_docs/tactics',
24
+ 'mkt_docs/deliverables',
25
+ 'mkt_docs/audit',
26
+ 'mkt_docs/spikes',
27
+ ].map((d) => path.join(cwd, d));
28
+
29
+ // 2. Project protocol (thin pointer — the operating contract is the skill).
30
+ // Deliberately short: duplicating the skill's rules here made them drift.
31
+ const protocolContent = `# Marketing Agentic SDLC — Project Protocol (pointer)
32
+
33
+ This project follows the Marketing Agentic SDLC Evidence-First process. The full
34
+ operating contract is the \`mkt-agentic-sdlc\` skill (installed in your agent's
35
+ skills directory); this file is only the minimal always-on pointer.
36
+
37
+ ## Rule Zero — Triage every request
38
+ - E1 Quick: single question or asset feedback (positioning opinion, copy critique). Answer directly; numbers still need a source.
39
+ - E2 Campaign: single-campaign or single-channel plan. Light path: mini-brief + targeted research + campaign document.
40
+ - E3 Full Plan: complete marketing plan. Full SOSTAC workflow via the skill: Discovery -> Research -> Situation -> Objectives -> Strategy -> Tactics -> Action -> Control -> Packaging.
41
+ - Research Spike: time-boxed market question; outcome in \`mkt_docs/spikes/RESEARCH_[topic].md\`.
42
+ - When in doubt, pick the higher level. Declare the chosen level when starting.
43
+
44
+ ## The three non-negotiables
45
+ 1. Evidence ledger: every market number carries an [EV-nn] reference (FACT / BENCHMARK / ASSUMPTION). No invented numbers, ever.
46
+ 2. Ask only what the user owns: facts come from the user, analysis comes from research. Never ask the user to do the analysis.
47
+ 3. Internal consistency: budget sums, funnel math and the objective->tactic->KPI chain are validated mechanically before delivery.
48
+
49
+ ## Where things live
50
+ - Vision (gate for E3): \`mkt_docs/vision/MKT_VISION.md\` — \`Status: DRAFT\` informs, \`Status: APPROVED\` binds.
51
+ - Evidence: \`mkt_docs/research/evidence_ledger.md\` (the single source for every number).
52
+ - Strategy artifacts: \`mkt_docs/strategy/\`; tactical artifacts: \`mkt_docs/tactics/\`; final deliverables: \`mkt_docs/deliverables/\`.
53
+ - Must-reads: \`mkt_docs/README.md\`; full generated manifest: \`mkt_docs/INDEX.md\`.
54
+ - If devPNT is available for this project, its M-VISION / plans / governed artifacts take over (Hybrid mode — see the skill).
55
+
56
+ ## Closure gate
57
+ Deliverables ship only after \`python <skill_dir>/scripts/mkt_check.py check\` is
58
+ CLEAN (where the validator is adopted) and the CMO review passed.
59
+
60
+ If the mkt-agentic-sdlc skill is not available in this client, ask the user to install it:
61
+ \`npm i -g @antoneeo/mkt-agentic-sdlc-skill\` (the skill installs automatically;
62
+ if npm blocks scripts, run \`npx mkt-sdlc-install-skill\`).
63
+ `;
64
+
65
+ console.log('🚀 Initializing Marketing Agentic SDLC workflow...');
66
+
67
+ // 3. Load templates from the single source (skill's templates.md)
68
+ let sections;
69
+ try {
70
+ sections = loadTemplates();
71
+ } catch (err) {
72
+ console.error(`❌ Cannot load templates: ${err.message}`);
73
+ process.exit(1);
74
+ }
75
+
76
+ let seedFiles;
77
+ try {
78
+ seedFiles = [
79
+ ['mkt_docs/README.md', templateFor(sections, 'mkt_docs/README.md')],
80
+ ['mkt_docs/vision/MKT_VISION.md', templateFor(sections, 'MKT_VISION.md')],
81
+ ['mkt_docs/vision/principles.md', templateFor(sections, 'principles.md')],
82
+ ['mkt_docs/research/evidence_ledger.md', templateFor(sections, 'evidence_ledger.md')],
83
+ // NOTE: INDEX.md is NOT seeded — it is generated by `mkt_check.py index`
84
+ // and would immediately fail validate.
85
+ ];
86
+ } catch (err) {
87
+ console.error(`❌ ${err.message}`);
88
+ process.exit(1);
89
+ }
90
+
91
+ // 4. Create directories
92
+ directories.forEach((dir) => {
93
+ if (!fs.existsSync(dir)) {
94
+ fs.mkdirSync(dir, { recursive: true });
95
+ console.log(`📁 Created directory: ${path.relative(cwd, dir)}`);
96
+ }
97
+ });
98
+
99
+ // 5. Write seed files (never overwrite)
100
+ const writeIfNotExists = (relPath, content, description) => {
101
+ const filePath = path.join(cwd, relPath);
102
+ if (!fs.existsSync(filePath)) {
103
+ fs.writeFileSync(filePath, content, 'utf8');
104
+ console.log(`📄 Created file: ${relPath}${description ? ` (${description})` : ''}`);
105
+ return true;
106
+ }
107
+ console.log(`⏭️ Skipped: ${relPath} already exists.`);
108
+ return false;
109
+ };
110
+
111
+ seedFiles.forEach(([relPath, content]) => writeIfNotExists(relPath, content));
112
+
113
+ // 6. Client discovery and protocol pointers
114
+ console.log('\n--- Environment Analysis ---');
115
+
116
+ const protocolFiles = {
117
+ claude: 'CLAUDE.md',
118
+ gemini: 'GEMINI.md',
119
+ codex: 'AGENTS.md',
120
+ antigravity: 'AGENTS.md', // Antigravity CLI reads AGENTS.md; single protocolContent reused.
121
+ };
122
+
123
+ // A protocol pointer that ALREADY existed was written by someone else — typically a
124
+ // sibling lens's init, which seeded the project with its own triage ladder. This init
125
+ // must not overwrite it (create-only is the T1 guarantee), so the second ladder is
126
+ // written aside and merged by hand.
127
+ let protocolPreexisting = false;
128
+
129
+ for (const client of CLIENTS) {
130
+ if (clientDetected(client)) {
131
+ console.log(`✅ ${client.label} detected.`);
132
+ const created = writeIfNotExists(protocolFiles[client.key], protocolContent, `${client.label} protocol pointer`);
133
+ if (!created) protocolPreexisting = true;
134
+ }
135
+ }
136
+
137
+ // Cursor/Windsurf (always recommended)
138
+ writeIfNotExists('.cursorrules', protocolContent, 'Cursor/Windsurf rules');
139
+
140
+ // 6b. Sibling lenses: additive only. Never edits a user-authored root file.
141
+ function installedSiblingLenses() {
142
+ const found = new Map();
143
+ for (const client of CLIENTS) {
144
+ if (!clientDetected(client)) continue;
145
+ const skillsDir = path.dirname(skillTarget(client));
146
+ for (const [dirName, lens] of Object.entries(SIBLING_LENSES)) {
147
+ if (fs.existsSync(path.join(skillsDir, dirName))) found.set(dirName, lens);
148
+ }
149
+ }
150
+ return found;
151
+ }
152
+
153
+ const siblings = installedSiblingLenses();
154
+ if (siblings.size > 0) {
155
+ const list = [...siblings].map(([dir, lens]) => `- \`${dir}\` — the **${lens}** lens`).join('\n');
156
+ console.log(`\n🔀 Sibling lens detected: ${[...siblings.keys()].join(', ')}.`);
157
+ const wrote = writeIfNotExists('AGENTIC_MULTI_LENS.md', `# Multi-lens project — routing note (additive)
158
+
159
+ This project has more than one lens of the Agentic SDLC family installed:
160
+
161
+ ${list}
162
+ - \`agentic-sdlc\` — the **code** lens
163
+
164
+ One \`ai_docs/\` tree, one project default (\`default_domain:\` in \`ai_docs/README.md\`),
165
+ one lens per unit of work. Before acting on any L2, L3 or Spike, run the domain router
166
+ in the skill's \`routing.md\`: it decides which lens's method and validation rules govern
167
+ that unit. L1 never reaches it. Never refer to a document whose meaning differs by lens
168
+ ("threat model", "vision", \`principles.md\`, \`handoff.md\`) by its bare name.
169
+
170
+ ${protocolPreexisting ? `**Merge step owed.** The always-on protocol pointer of this project (\`CLAUDE.md\` /
171
+ \`GEMINI.md\` / \`AGENTS.md\` / \`.cursorrules\`) was written by another lens's init and
172
+ carries ITS triage ladder. This init did not overwrite it. Add the marketing lens's ladder
173
+ to that file by hand — the pointer below — so both are always loaded.
174
+
175
+ ## Rule Zero — Triage every request (marketing lens)
176
+ - E1 Question: one answer from the existing plan, no document written.
177
+ - E2 Campaign: a single campaign or channel, on an approved strategy.
178
+ - E3 Full engagement: the nine-phase SOSTAC workflow, evidence ledger and all
179
+ three validator gates.
180
+ ` : `The always-on protocol pointer for the marketing lens was created by this init. When you
181
+ install another lens over this project, its init will leave its own ladder here for you
182
+ to merge.
183
+ `}
184
+ This file is NOT auto-loaded by any client: it is a note for you, deliberately additive.
185
+ Delete it once the merge is done.
186
+ `, 'multi-lens routing note');
187
+ if (wrote && protocolPreexisting) {
188
+ console.log(' ⚠️ A protocol pointer already existed and was NOT overwritten.');
189
+ console.log(' Merge the code-lens ladder from AGENTIC_MULTI_LENS.md into it by hand.');
190
+ }
191
+ }
192
+
193
+ // 7. Generate mkt_docs/INDEX.md so the very first `validate` is already clean.
194
+ // The manifest is generated, never seeded: delegate to the validator if Python is available.
195
+ const validator = path.join(SKILL_SOURCE, 'scripts', 'mkt_check.py');
196
+ let indexed = false;
197
+ for (const py of ['python', 'python3', 'py']) {
198
+ try {
199
+ execSync(`${py} "${validator}" index --root "${cwd}"`, { stdio: 'ignore' });
200
+ console.log('📇 Generated mkt_docs/INDEX.md (document manifest).');
201
+ indexed = true;
202
+ break;
203
+ } catch (e) { /* try the next interpreter */ }
204
+ }
205
+ if (!indexed) {
206
+ console.log('ℹ️ Python not found: generate the manifest later with '
207
+ + '"python <skill_dir>/scripts/mkt_check.py index" (validate reports it until then).');
208
+ }
209
+
210
+ console.log('\n✅ Setup completed successfully!');
211
+ console.log('💡 Next steps:');
212
+ console.log(' 1. Make sure the mkt-agentic-sdlc skill is installed (mkt-sdlc-install-skill).');
213
+ console.log(' 2. Restart/open the project in your AI client so it reads the protocol pointer.');
214
+ console.log(' 3. Start an E3 engagement: the skill runs Discovery (its questions) before anything else.');