@planu/cli 5.3.60 → 5.3.62
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/CHANGELOG.md +24 -0
- package/dist/.planu-build.json +1 -1
- package/dist/engine/challenge-prioritizer.js +2 -1
- package/dist/tools/challenge-spec.js +1 -1
- package/dist/tools/update-status/dod-gates.js +20 -10
- package/dist/tools/update-status/file-sync.js +37 -5
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -4
- package/package.json +1 -1
- package/planu-plugin.json +1 -1
- package/dist/config/mobile-ci-templates/android-github-actions.yml +0 -149
- package/dist/config/mobile-ci-templates/ios-github-actions.yml +0 -120
- package/dist/config/spec-templates.json +0 -125
- package/dist/types/agent-guarantees.d.ts +0 -73
- package/dist/types/agent-guarantees.js +0 -3
- package/dist/types/google-workspace.d.ts +0 -39
- package/dist/types/google-workspace.js +0 -3
- package/dist/types/mcp-gateway.d.ts +0 -34
- package/dist/types/mcp-gateway.js +0 -3
- package/dist/types/multi-repo.d.ts +0 -39
- package/dist/types/multi-repo.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## [5.3.62] - 2026-08-26
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
- fix(SPEC-1639,1640,1641,1642): four dogfood defects in challenge, gates, coverage and sync
|
|
5
|
+
|
|
6
|
+
### Chores
|
|
7
|
+
- chore(planu): close SPEC-1639, SPEC-1640, SPEC-1641 and SPEC-1642
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [5.3.61] - 2026-08-26
|
|
11
|
+
|
|
12
|
+
### Refactoring
|
|
13
|
+
- refactor(SPEC-1636): remove two unenforced agent rules and migrate their conventions
|
|
14
|
+
- refactor(SPEC-1638): delete orphaned config assets and dead type modules
|
|
15
|
+
|
|
16
|
+
### Chores
|
|
17
|
+
- chore(SPEC-1636): close spec with dual-provider implementation review evidence
|
|
18
|
+
- chore(SPEC-1636): approve after five-round dual-provider review
|
|
19
|
+
- chore(SPEC-1638): record done-state lifecycle artifacts
|
|
20
|
+
- chore(SPEC-1638): qualify the ios template path in canonical scope
|
|
21
|
+
- chore(SPEC-1638): declare executable scenarios for the compliance runner
|
|
22
|
+
- chore(SPEC-1638): mark acceptance criteria done after verified implementation
|
|
23
|
+
|
|
24
|
+
|
|
1
25
|
## [5.3.60] - 2026-08-26
|
|
2
26
|
|
|
3
27
|
### Bug Fixes
|
package/dist/.planu-build.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"commit":"
|
|
1
|
+
{"schemaVersion":1,"commit":"653317c22ebdf21ad6b7f82f5d86dd042b05aaab"}
|
|
@@ -72,6 +72,7 @@ export function buildPrioritizedSummary(top3) {
|
|
|
72
72
|
return '';
|
|
73
73
|
}
|
|
74
74
|
const lines = top3.map((s) => `${s.rank}. ${s.scenario}`);
|
|
75
|
-
|
|
75
|
+
const noun = top3.length === 1 ? 'thing' : 'things';
|
|
76
|
+
return `Here are the ${String(top3.length)} ${noun} you MUST address before coding:\n${lines.join('\n')}`;
|
|
76
77
|
}
|
|
77
78
|
//# sourceMappingURL=challenge-prioritizer.js.map
|
|
@@ -314,7 +314,7 @@ export async function handleChallengeSpec(args, server) {
|
|
|
314
314
|
totalScenarios: failureScenarios.length,
|
|
315
315
|
actionableScenarios: failureScenariosScored.length,
|
|
316
316
|
suppressedLowRelevanceScenarios: suppressedScenarioCount + concurrencySuppressedCount,
|
|
317
|
-
shownByDefault:
|
|
317
|
+
shownByDefault: prioritizedBlocking.length,
|
|
318
318
|
mustAddressBeforeCoding: prioritizedSummary,
|
|
319
319
|
remainingAdvisories: advisoryIdentities,
|
|
320
320
|
gateStatus: gateState.gateStatus,
|
|
@@ -634,14 +634,20 @@ export async function checkSpecReviewGate(specId, projectId, _forceApprove) {
|
|
|
634
634
|
fixHint: 'Resolve the spec review blockers and have planu-spec-reviewer write updated evidence, then retry approval.',
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
|
-
|
|
638
|
-
|
|
637
|
+
const specReviewerBlockers = [];
|
|
638
|
+
if (review.reviewer.kind !== 'spec-review-agent') {
|
|
639
|
+
specReviewerBlockers.push(`reviewer.kind was ${review.reviewer.kind}. Expected spec-review-agent.`);
|
|
640
|
+
}
|
|
641
|
+
if (review.reviewer.agent !== 'planu-spec-reviewer') {
|
|
642
|
+
specReviewerBlockers.push(`reviewer.agent was ${review.reviewer.agent}. Expected planu-spec-reviewer.`);
|
|
643
|
+
}
|
|
644
|
+
if (specReviewerBlockers.length > 0) {
|
|
639
645
|
return specReviewGateError({
|
|
640
646
|
specId,
|
|
641
647
|
error: 'spec_review_wrong_reviewer',
|
|
642
648
|
message: 'Approval requires a dedicated spec reviewer. The implementation reviewer cannot approve the spec plan.',
|
|
643
|
-
blockers:
|
|
644
|
-
fixHint: 'Have planu-spec-reviewer
|
|
649
|
+
blockers: specReviewerBlockers,
|
|
650
|
+
fixHint: 'Have planu-spec-reviewer write the review artifact with reviewer.kind spec-review-agent and reviewer.agent planu-spec-reviewer, then retry approval.',
|
|
645
651
|
});
|
|
646
652
|
}
|
|
647
653
|
return null;
|
|
@@ -698,16 +704,20 @@ export async function checkImplementationReviewGate(specId, projectId, _force) {
|
|
|
698
704
|
fixHint: 'Resolve the implementation review blockers and have planu-implementation-reviewer write updated evidence, then retry done.',
|
|
699
705
|
});
|
|
700
706
|
}
|
|
701
|
-
|
|
702
|
-
|
|
707
|
+
const implementationReviewerBlockers = [];
|
|
708
|
+
if (review.reviewer.kind !== 'implementation-review-agent') {
|
|
709
|
+
implementationReviewerBlockers.push(`reviewer.kind was ${review.reviewer.kind}. Expected implementation-review-agent.`);
|
|
710
|
+
}
|
|
711
|
+
if (review.reviewer.agent !== 'planu-implementation-reviewer') {
|
|
712
|
+
implementationReviewerBlockers.push(`reviewer.agent was ${review.reviewer.agent}. Expected planu-implementation-reviewer.`);
|
|
713
|
+
}
|
|
714
|
+
if (implementationReviewerBlockers.length > 0) {
|
|
703
715
|
return implementationReviewGateError({
|
|
704
716
|
specId,
|
|
705
717
|
error: 'implementation_review_wrong_reviewer',
|
|
706
718
|
message: 'Done requires the recognized independent implementation reviewer identity.',
|
|
707
|
-
blockers:
|
|
708
|
-
|
|
709
|
-
],
|
|
710
|
-
fixHint: 'Have planu-implementation-reviewer (with the recognized identity) write the review artifact, then retry done.',
|
|
719
|
+
blockers: implementationReviewerBlockers,
|
|
720
|
+
fixHint: 'Have planu-implementation-reviewer write the review artifact with reviewer.kind implementation-review-agent and reviewer.agent planu-implementation-reviewer, then retry done.',
|
|
711
721
|
});
|
|
712
722
|
}
|
|
713
723
|
let implementerActor;
|
|
@@ -250,13 +250,45 @@ function isLeanSpecContent(content) {
|
|
|
250
250
|
* SPEC-630: Remove done criteria entries from lean spec and annotate the count on the criteria key.
|
|
251
251
|
* Only call this after markAllCriteriaDone — assumes all completed criteria have `done: true`.
|
|
252
252
|
*/
|
|
253
|
+
function indentWidth(line) {
|
|
254
|
+
return /^[ \t]*/.exec(line)?.[0].length ?? 0;
|
|
255
|
+
}
|
|
256
|
+
function isNestedUnder(line, itemIndent) {
|
|
257
|
+
return line.trim().length === 0 || indentWidth(line) > itemIndent.length;
|
|
258
|
+
}
|
|
259
|
+
function isDoneTrueField(line, fieldIndent) {
|
|
260
|
+
return new RegExp(`^${fieldIndent}done:[ \\t]*true[ \\t]*(?:#.*)?$`).test(line);
|
|
261
|
+
}
|
|
253
262
|
function stripDoneCriteria(content) {
|
|
263
|
+
const lines = content.split('\n');
|
|
264
|
+
const kept = [];
|
|
254
265
|
let doneCount = 0;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
266
|
+
let index = 0;
|
|
267
|
+
while (index < lines.length) {
|
|
268
|
+
const line = lines[index] ?? '';
|
|
269
|
+
const itemIndent = /^([ \t]+)- text:/.exec(line)?.[1];
|
|
270
|
+
if (itemIndent === undefined) {
|
|
271
|
+
kept.push(line);
|
|
272
|
+
index += 1;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
let end = index + 1;
|
|
276
|
+
while (end < lines.length && isNestedUnder(lines[end] ?? '', itemIndent)) {
|
|
277
|
+
end += 1;
|
|
278
|
+
}
|
|
279
|
+
const item = lines.slice(index + 1, end);
|
|
280
|
+
const firstField = item.find((entry) => entry.trim().length > 0);
|
|
281
|
+
const fieldIndent = firstField === undefined ? '' : (/^[ \t]*/.exec(firstField)?.[0] ?? '');
|
|
282
|
+
const isDone = firstField !== undefined && item.some((entry) => isDoneTrueField(entry, fieldIndent));
|
|
283
|
+
if (isDone) {
|
|
284
|
+
doneCount += 1;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
kept.push(line, ...item);
|
|
288
|
+
}
|
|
289
|
+
index = end;
|
|
290
|
+
}
|
|
291
|
+
return kept.join('\n').replace(/^(criteria:)(\s*#.*)?$/m, `$1 # ${String(doneCount)} done`);
|
|
260
292
|
}
|
|
261
293
|
export async function tryReconcile(newStatus, specId, projectId) {
|
|
262
294
|
if (newStatus !== 'done') {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -170,7 +170,6 @@ export * from './spec-lock-v2.js';
|
|
|
170
170
|
export * from './diagram.js';
|
|
171
171
|
export * from './browser-validator.js';
|
|
172
172
|
export * from './build-freshness.js';
|
|
173
|
-
export * from './google-workspace.js';
|
|
174
173
|
export * from './skill-eval.js';
|
|
175
174
|
export * from './spec-marketplace.js';
|
|
176
175
|
export * from './spec-quality.js';
|
|
@@ -206,11 +205,9 @@ export * from './code-graph-integration.js';
|
|
|
206
205
|
export * from './e2e-test-generator.js';
|
|
207
206
|
export * from './drift-watcher.js';
|
|
208
207
|
export * from './audit.js';
|
|
209
|
-
export * from './multi-repo.js';
|
|
210
208
|
export * from './compliance-tests.js';
|
|
211
209
|
export * from './auto-promoter.js';
|
|
212
210
|
export * from './cost-guardrails.js';
|
|
213
|
-
export * from './mcp-gateway.js';
|
|
214
211
|
export * from './health.js';
|
|
215
212
|
export * from './context-profile.js';
|
|
216
213
|
export * from './ears.js';
|
|
@@ -230,7 +227,6 @@ export * from './compliance-gate.js';
|
|
|
230
227
|
export * from './schema-parity.js';
|
|
231
228
|
export * from './auto-update.js';
|
|
232
229
|
export * from './tdd-enforcement.js';
|
|
233
|
-
export * from './agent-guarantees.js';
|
|
234
230
|
export * from './clarification.js';
|
|
235
231
|
export * from './spec-format.js';
|
|
236
232
|
export * from './elicit-schema.js';
|
package/dist/types/index.js
CHANGED
|
@@ -167,7 +167,6 @@ export * from './spec-lock-v2.js';
|
|
|
167
167
|
export * from './diagram.js';
|
|
168
168
|
export * from './browser-validator.js';
|
|
169
169
|
export * from './build-freshness.js';
|
|
170
|
-
export * from './google-workspace.js';
|
|
171
170
|
export * from './skill-eval.js';
|
|
172
171
|
export * from './spec-marketplace.js';
|
|
173
172
|
export * from './spec-quality.js';
|
|
@@ -203,11 +202,9 @@ export * from './code-graph-integration.js';
|
|
|
203
202
|
export * from './e2e-test-generator.js';
|
|
204
203
|
export * from './drift-watcher.js';
|
|
205
204
|
export * from './audit.js';
|
|
206
|
-
export * from './multi-repo.js';
|
|
207
205
|
export * from './compliance-tests.js';
|
|
208
206
|
export * from './auto-promoter.js';
|
|
209
207
|
export * from './cost-guardrails.js';
|
|
210
|
-
export * from './mcp-gateway.js';
|
|
211
208
|
export * from './health.js';
|
|
212
209
|
export * from './context-profile.js';
|
|
213
210
|
export * from './ears.js';
|
|
@@ -227,7 +224,6 @@ export * from './compliance-gate.js';
|
|
|
227
224
|
export * from './schema-parity.js';
|
|
228
225
|
export * from './auto-update.js';
|
|
229
226
|
export * from './tdd-enforcement.js';
|
|
230
|
-
export * from './agent-guarantees.js';
|
|
231
227
|
export * from './clarification.js';
|
|
232
228
|
export * from './spec-format.js';
|
|
233
229
|
export * from './elicit-schema.js';
|
package/package.json
CHANGED
package/planu-plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dev.planu.cli",
|
|
3
3
|
"displayName": "Planu — Spec Driven Development",
|
|
4
4
|
"description": "Manage software specs, estimations, and autonomous SDD workflows. Language-agnostic MCP server for Claude Code.",
|
|
5
|
-
"version": "5.3.
|
|
5
|
+
"version": "5.3.62",
|
|
6
6
|
"icon": "assets/plugin/icon.svg",
|
|
7
7
|
"command": ["npx", "@planu/cli@latest"],
|
|
8
8
|
"packageName": "@planu/cli",
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
name: Android CI/CD
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, develop]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, develop]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
|
|
12
|
-
android-test:
|
|
13
|
-
name: Android — Gradle Unit Tests
|
|
14
|
-
runs-on: ubuntu-latest
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout code
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
|
|
19
|
-
- name: Setup JDK
|
|
20
|
-
uses: actions/setup-java@v4
|
|
21
|
-
with:
|
|
22
|
-
java-version: '17'
|
|
23
|
-
distribution: temurin
|
|
24
|
-
|
|
25
|
-
- name: Cache Gradle packages
|
|
26
|
-
uses: actions/cache@v4
|
|
27
|
-
with:
|
|
28
|
-
path: |
|
|
29
|
-
~/.gradle/caches
|
|
30
|
-
~/.gradle/wrapper
|
|
31
|
-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
32
|
-
restore-keys: ${{ runner.os }}-gradle-
|
|
33
|
-
|
|
34
|
-
- name: Grant Gradle execute permission
|
|
35
|
-
run: chmod +x gradlew
|
|
36
|
-
|
|
37
|
-
- name: Run unit tests
|
|
38
|
-
run: ./gradlew :{{module}}:testDebugUnitTest
|
|
39
|
-
|
|
40
|
-
- name: Upload test reports
|
|
41
|
-
uses: actions/upload-artifact@v4
|
|
42
|
-
with:
|
|
43
|
-
name: test-results
|
|
44
|
-
path: '{{module}}/build/reports/tests/'
|
|
45
|
-
if-no-files-found: warn
|
|
46
|
-
|
|
47
|
-
android-sign:
|
|
48
|
-
name: Android — Sign Release AAB
|
|
49
|
-
runs-on: ubuntu-latest
|
|
50
|
-
needs: android-test
|
|
51
|
-
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main'
|
|
52
|
-
env:
|
|
53
|
-
KEYSTORE_FILE: ${{ secrets.KEYSTORE_FILE }}
|
|
54
|
-
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
|
55
|
-
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
|
56
|
-
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
|
57
|
-
steps:
|
|
58
|
-
- name: Checkout code
|
|
59
|
-
uses: actions/checkout@v4
|
|
60
|
-
|
|
61
|
-
- name: Setup JDK
|
|
62
|
-
uses: actions/setup-java@v4
|
|
63
|
-
with:
|
|
64
|
-
java-version: '17'
|
|
65
|
-
distribution: temurin
|
|
66
|
-
|
|
67
|
-
- name: Cache Gradle packages
|
|
68
|
-
uses: actions/cache@v4
|
|
69
|
-
with:
|
|
70
|
-
path: |
|
|
71
|
-
~/.gradle/caches
|
|
72
|
-
~/.gradle/wrapper
|
|
73
|
-
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
74
|
-
restore-keys: ${{ runner.os }}-gradle-
|
|
75
|
-
|
|
76
|
-
- name: Grant Gradle execute permission
|
|
77
|
-
run: chmod +x gradlew
|
|
78
|
-
|
|
79
|
-
- name: Decode keystore
|
|
80
|
-
run: echo "$KEYSTORE_FILE" | base64 --decode > keystore.jks
|
|
81
|
-
env:
|
|
82
|
-
KEYSTORE_FILE: ${{ secrets.KEYSTORE_FILE }}
|
|
83
|
-
|
|
84
|
-
- name: Build signed release AAB
|
|
85
|
-
run: |
|
|
86
|
-
./gradlew :{{module}}:bundleRelease \
|
|
87
|
-
-Pandroid.injected.signing.store.file=$(pwd)/keystore.jks \
|
|
88
|
-
-Pandroid.injected.signing.store.password="$KEYSTORE_PASSWORD" \
|
|
89
|
-
-Pandroid.injected.signing.key.alias="$KEY_ALIAS" \
|
|
90
|
-
-Pandroid.injected.signing.key.password="$KEY_PASSWORD"
|
|
91
|
-
env:
|
|
92
|
-
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
|
|
93
|
-
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
|
94
|
-
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
|
95
|
-
|
|
96
|
-
- name: Upload signed AAB
|
|
97
|
-
uses: actions/upload-artifact@v4
|
|
98
|
-
with:
|
|
99
|
-
name: release-aab
|
|
100
|
-
path: '{{module}}/build/outputs/bundle/release/*.aab'
|
|
101
|
-
|
|
102
|
-
android-deploy:
|
|
103
|
-
name: Android — Play Console Deploy
|
|
104
|
-
runs-on: ubuntu-latest
|
|
105
|
-
needs: android-sign
|
|
106
|
-
if: github.ref == 'refs/heads/main'
|
|
107
|
-
env:
|
|
108
|
-
PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }}
|
|
109
|
-
steps:
|
|
110
|
-
- name: Checkout code
|
|
111
|
-
uses: actions/checkout@v4
|
|
112
|
-
|
|
113
|
-
- name: Download signed AAB
|
|
114
|
-
uses: actions/download-artifact@v4
|
|
115
|
-
with:
|
|
116
|
-
name: release-aab
|
|
117
|
-
path: ./release
|
|
118
|
-
|
|
119
|
-
- name: Setup Ruby for Fastlane
|
|
120
|
-
uses: ruby/setup-ruby@v1
|
|
121
|
-
with:
|
|
122
|
-
ruby-version: 'bundler-cache: true'
|
|
123
|
-
|
|
124
|
-
- name: Install Fastlane
|
|
125
|
-
run: gem install fastlane --no-document
|
|
126
|
-
|
|
127
|
-
- name: Decode Play Store JSON key
|
|
128
|
-
run: echo "$PLAY_STORE_JSON_KEY" > play-store-key.json
|
|
129
|
-
env:
|
|
130
|
-
PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }}
|
|
131
|
-
|
|
132
|
-
- name: Upload to Play Console (internal track)
|
|
133
|
-
run: |
|
|
134
|
-
fastlane supply \
|
|
135
|
-
--aab ./release/{{module}}/build/outputs/bundle/release/*.aab \
|
|
136
|
-
--package_name "{{bundleId}}" \
|
|
137
|
-
--track internal \
|
|
138
|
-
--json_key ./play-store-key.json
|
|
139
|
-
|
|
140
|
-
# Required GitHub Secrets:
|
|
141
|
-
# KEYSTORE_FILE — Base64-encoded .jks keystore file
|
|
142
|
-
# KEYSTORE_PASSWORD — Password for the keystore file
|
|
143
|
-
# KEY_ALIAS — Alias of the signing key in the keystore
|
|
144
|
-
# KEY_PASSWORD — Password for the signing key
|
|
145
|
-
# PLAY_STORE_JSON_KEY — JSON content of the Google Play service account key
|
|
146
|
-
#
|
|
147
|
-
# Placeholders:
|
|
148
|
-
# {{module}} — Gradle module name (e.g. app)
|
|
149
|
-
# {{bundleId}} — Android application ID (e.g. com.example.myapp)
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
name: iOS CI/CD
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main, develop]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main, develop]
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
|
|
12
|
-
ios-test:
|
|
13
|
-
name: iOS — Xcode Build & Test
|
|
14
|
-
runs-on: macos-latest
|
|
15
|
-
env:
|
|
16
|
-
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
|
17
|
-
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}
|
|
18
|
-
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
|
19
|
-
steps:
|
|
20
|
-
- name: Checkout code
|
|
21
|
-
uses: actions/checkout@v4
|
|
22
|
-
|
|
23
|
-
- name: Select Xcode version
|
|
24
|
-
run: sudo xcode-select -s /Applications/Xcode.app
|
|
25
|
-
|
|
26
|
-
- name: Build and test (Xcode)
|
|
27
|
-
run: |
|
|
28
|
-
xcodebuild clean build test \
|
|
29
|
-
-scheme "{{scheme}}" \
|
|
30
|
-
-destination 'platform=iOS Simulator,name=iPhone 15,OS=latest' \
|
|
31
|
-
CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \
|
|
32
|
-
| xcpretty && exit "${PIPESTATUS[0]}"
|
|
33
|
-
|
|
34
|
-
ios-testflight:
|
|
35
|
-
name: iOS — TestFlight Upload
|
|
36
|
-
runs-on: macos-latest
|
|
37
|
-
needs: ios-test
|
|
38
|
-
if: github.ref == 'refs/heads/develop'
|
|
39
|
-
env:
|
|
40
|
-
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
|
41
|
-
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}
|
|
42
|
-
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
|
43
|
-
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
|
|
44
|
-
steps:
|
|
45
|
-
- name: Checkout code
|
|
46
|
-
uses: actions/checkout@v4
|
|
47
|
-
|
|
48
|
-
- name: Select Xcode version
|
|
49
|
-
run: sudo xcode-select -s /Applications/Xcode.app
|
|
50
|
-
|
|
51
|
-
- name: Setup Ruby for Fastlane
|
|
52
|
-
uses: ruby/setup-ruby@v1
|
|
53
|
-
with:
|
|
54
|
-
ruby-version: 'bundler-cache: true'
|
|
55
|
-
|
|
56
|
-
- name: Install Fastlane
|
|
57
|
-
run: gem install fastlane --no-document
|
|
58
|
-
|
|
59
|
-
- name: Build IPA
|
|
60
|
-
run: |
|
|
61
|
-
fastlane gym \
|
|
62
|
-
--scheme "{{scheme}}" \
|
|
63
|
-
--export_method app-store \
|
|
64
|
-
--output_directory ./build
|
|
65
|
-
env:
|
|
66
|
-
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
|
|
67
|
-
|
|
68
|
-
- name: Upload to TestFlight
|
|
69
|
-
run: fastlane pilot upload --ipa ./build/*.ipa --skip_waiting_for_build_processing true
|
|
70
|
-
|
|
71
|
-
ios-appstore:
|
|
72
|
-
name: iOS — App Store Submission
|
|
73
|
-
runs-on: macos-latest
|
|
74
|
-
needs: ios-test
|
|
75
|
-
if: github.ref == 'refs/heads/main'
|
|
76
|
-
env:
|
|
77
|
-
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
|
|
78
|
-
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}
|
|
79
|
-
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
|
80
|
-
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
|
|
81
|
-
steps:
|
|
82
|
-
- name: Checkout code
|
|
83
|
-
uses: actions/checkout@v4
|
|
84
|
-
|
|
85
|
-
- name: Select Xcode version
|
|
86
|
-
run: sudo xcode-select -s /Applications/Xcode.app
|
|
87
|
-
|
|
88
|
-
- name: Setup Ruby for Fastlane
|
|
89
|
-
uses: ruby/setup-ruby@v1
|
|
90
|
-
with:
|
|
91
|
-
ruby-version: 'bundler-cache: true'
|
|
92
|
-
|
|
93
|
-
- name: Install Fastlane
|
|
94
|
-
run: gem install fastlane --no-document
|
|
95
|
-
|
|
96
|
-
- name: Build IPA (production)
|
|
97
|
-
run: |
|
|
98
|
-
fastlane gym \
|
|
99
|
-
--scheme "{{scheme}}" \
|
|
100
|
-
--configuration Release \
|
|
101
|
-
--export_method app-store \
|
|
102
|
-
--output_directory ./build
|
|
103
|
-
env:
|
|
104
|
-
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
|
|
105
|
-
|
|
106
|
-
- name: Submit to App Store
|
|
107
|
-
run: |
|
|
108
|
-
fastlane deliver \
|
|
109
|
-
--ipa ./build/*.ipa \
|
|
110
|
-
--submit_for_review false \
|
|
111
|
-
--automatic_release false
|
|
112
|
-
|
|
113
|
-
# Required GitHub Secrets:
|
|
114
|
-
# APPLE_API_KEY — Base64-encoded .p8 private key from App Store Connect
|
|
115
|
-
# APPLE_API_ISSUER_ID — Issuer ID from App Store Connect API keys page
|
|
116
|
-
# APPLE_API_KEY_ID — Key ID from App Store Connect API keys page
|
|
117
|
-
# MATCH_PASSWORD — Encryption passphrase for Fastlane Match certificates
|
|
118
|
-
#
|
|
119
|
-
# Placeholders:
|
|
120
|
-
# {{scheme}} — Replace with your Xcode scheme name (e.g. MyApp)
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"huTemplates": {
|
|
3
|
-
"feature": {
|
|
4
|
-
"descriptionFormat": "As a {role}, I want {goal}, so that {benefit}.",
|
|
5
|
-
"sections": ["Description", "Acceptance Criteria", "Out of Scope", "Dependencies", "Tags"]
|
|
6
|
-
},
|
|
7
|
-
"bugfix": {
|
|
8
|
-
"descriptionFormat": "Bug: {description}.\n\n**Expected behavior:** {expected}\n\n**Actual behavior:** {actual}\n\n**Steps to reproduce:**\n1. {steps}",
|
|
9
|
-
"sections": [
|
|
10
|
-
"Bug Description",
|
|
11
|
-
"Steps to Reproduce",
|
|
12
|
-
"Expected vs Actual",
|
|
13
|
-
"Root Cause Analysis",
|
|
14
|
-
"Fix Criteria",
|
|
15
|
-
"Regression Tests",
|
|
16
|
-
"Dependencies",
|
|
17
|
-
"Tags"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
|
-
"refactor": {
|
|
21
|
-
"descriptionFormat": "Refactoring: {what}.\n\nMotivation: {motivation}\n\nExpected improvements: {improvements}",
|
|
22
|
-
"sections": [
|
|
23
|
-
"Refactoring Description",
|
|
24
|
-
"Motivation",
|
|
25
|
-
"Current State",
|
|
26
|
-
"Target State",
|
|
27
|
-
"Acceptance Criteria",
|
|
28
|
-
"Migration Plan",
|
|
29
|
-
"Dependencies",
|
|
30
|
-
"Tags"
|
|
31
|
-
]
|
|
32
|
-
},
|
|
33
|
-
"infra": {
|
|
34
|
-
"descriptionFormat": "Infrastructure change: {description}.\n\nEnvironments affected: {environments}\n\nRollback plan: {rollback}",
|
|
35
|
-
"sections": [
|
|
36
|
-
"Infrastructure Description",
|
|
37
|
-
"Environments Affected",
|
|
38
|
-
"Schema Changes",
|
|
39
|
-
"Acceptance Criteria",
|
|
40
|
-
"Rollback Plan",
|
|
41
|
-
"Dependencies",
|
|
42
|
-
"Tags"
|
|
43
|
-
]
|
|
44
|
-
},
|
|
45
|
-
"docs": {
|
|
46
|
-
"descriptionFormat": "Documentation: {description}.\n\nTarget audience: {audience}\n\nFormat: {format}",
|
|
47
|
-
"sections": [
|
|
48
|
-
"Documentation Description",
|
|
49
|
-
"Target Audience",
|
|
50
|
-
"Content Outline",
|
|
51
|
-
"Acceptance Criteria",
|
|
52
|
-
"Dependencies",
|
|
53
|
-
"Tags"
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
"project": {
|
|
57
|
-
"descriptionFormat": "Project: {description}.\n\nObjective: {objective}\n\nTimeline: {timeline}",
|
|
58
|
-
"sections": ["Description", "Objective", "Acceptance Criteria", "Dependencies", "Tags"]
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
"fichaTemplates": {
|
|
62
|
-
"trivial": {
|
|
63
|
-
"sections": ["Metadata", "Estimation", "Files", "Verification"],
|
|
64
|
-
"excludeSections": ["DataFlow", "Interfaces", "Behavior"]
|
|
65
|
-
},
|
|
66
|
-
"feature": {
|
|
67
|
-
"sections": [
|
|
68
|
-
"Metadata",
|
|
69
|
-
"Estimation",
|
|
70
|
-
"Interfaces",
|
|
71
|
-
"Behavior",
|
|
72
|
-
"DataFlow",
|
|
73
|
-
"Files",
|
|
74
|
-
"Verification",
|
|
75
|
-
"TechnicalNotes",
|
|
76
|
-
"PostImplementation"
|
|
77
|
-
],
|
|
78
|
-
"excludeSections": []
|
|
79
|
-
},
|
|
80
|
-
"cross-module": {
|
|
81
|
-
"sections": [
|
|
82
|
-
"Metadata",
|
|
83
|
-
"Estimation",
|
|
84
|
-
"AffectedModules",
|
|
85
|
-
"Interfaces",
|
|
86
|
-
"Behavior",
|
|
87
|
-
"DataFlow",
|
|
88
|
-
"Files",
|
|
89
|
-
"Verification",
|
|
90
|
-
"TechnicalNotes",
|
|
91
|
-
"PostImplementation"
|
|
92
|
-
],
|
|
93
|
-
"excludeSections": []
|
|
94
|
-
},
|
|
95
|
-
"architectural": {
|
|
96
|
-
"sections": [
|
|
97
|
-
"Metadata",
|
|
98
|
-
"Estimation",
|
|
99
|
-
"ArchitecturalImpact",
|
|
100
|
-
"AffectedModules",
|
|
101
|
-
"Interfaces",
|
|
102
|
-
"Behavior",
|
|
103
|
-
"DataFlow",
|
|
104
|
-
"Files",
|
|
105
|
-
"Verification",
|
|
106
|
-
"TechnicalNotes",
|
|
107
|
-
"PostImplementation"
|
|
108
|
-
],
|
|
109
|
-
"excludeSections": []
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
"stackTerminology": {
|
|
113
|
-
"typescript": { "types": "Interfaces/Types", "models": "Interfaces", "structLabel": "TypeScript Interfaces" },
|
|
114
|
-
"javascript": { "types": "Types/JSDoc", "models": "Schemas", "structLabel": "JavaScript Schemas" },
|
|
115
|
-
"python": { "types": "Models/Types", "models": "Models", "structLabel": "Python Models" },
|
|
116
|
-
"go": { "types": "Structs", "models": "Structs", "structLabel": "Go Structs" },
|
|
117
|
-
"rust": { "types": "Structs/Enums", "models": "Structs", "structLabel": "Rust Structs" },
|
|
118
|
-
"java": { "types": "Classes/Interfaces", "models": "POJOs", "structLabel": "Java Classes" },
|
|
119
|
-
"kotlin": { "types": "Data Classes/Interfaces", "models": "Data Classes", "structLabel": "Kotlin Data Classes" },
|
|
120
|
-
"swift": { "types": "Structs/Protocols", "models": "Structs", "structLabel": "Swift Structs" },
|
|
121
|
-
"csharp": { "types": "Classes/Interfaces", "models": "Models", "structLabel": "C# Classes" },
|
|
122
|
-
"ruby": { "types": "Classes/Modules", "models": "Models", "structLabel": "Ruby Classes" },
|
|
123
|
-
"php": { "types": "Classes/Interfaces", "models": "Models", "structLabel": "PHP Classes" }
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export type AgentLifecycleState = 'spawned' | 'running' | 'completed' | 'failed' | 'timed_out' | 'stalled';
|
|
2
|
-
export interface TrackedAgent {
|
|
3
|
-
id: string;
|
|
4
|
-
taskDescription: string;
|
|
5
|
-
spawnedAt: string;
|
|
6
|
-
lastHeartbeat: string | null;
|
|
7
|
-
state: AgentLifecycleState;
|
|
8
|
-
timeoutMs: number;
|
|
9
|
-
retryCount: number;
|
|
10
|
-
maxRetries: number;
|
|
11
|
-
expectedDeliverables: string[];
|
|
12
|
-
actualDeliverables: string[];
|
|
13
|
-
completionScore: number;
|
|
14
|
-
error: string | null;
|
|
15
|
-
parentAgentId: string | null;
|
|
16
|
-
}
|
|
17
|
-
export interface AgentCompletionReport {
|
|
18
|
-
sessionId: string;
|
|
19
|
-
timestamp: string;
|
|
20
|
-
totalAgents: number;
|
|
21
|
-
completed: number;
|
|
22
|
-
failed: number;
|
|
23
|
-
stalled: number;
|
|
24
|
-
timedOut: number;
|
|
25
|
-
partial: number;
|
|
26
|
-
agents: TrackedAgent[];
|
|
27
|
-
overallScore: number;
|
|
28
|
-
}
|
|
29
|
-
export interface AgentGuaranteeConfig {
|
|
30
|
-
defaultTimeoutMs: number;
|
|
31
|
-
heartbeatIntervalMs: number;
|
|
32
|
-
maxRetries: number;
|
|
33
|
-
stallThresholdMs: number;
|
|
34
|
-
blockSessionEnd: boolean;
|
|
35
|
-
autoRetryOnStall: boolean;
|
|
36
|
-
autoRetryOnFailure: boolean;
|
|
37
|
-
}
|
|
38
|
-
export type AgentLifecycleEventName = 'agent:spawned' | 'agent:heartbeat' | 'agent:completed' | 'agent:failed' | 'agent:stalled' | 'agent:timed_out' | 'agent:retry';
|
|
39
|
-
export interface AgentLifecycleEvent {
|
|
40
|
-
name: AgentLifecycleEventName;
|
|
41
|
-
agentId: string;
|
|
42
|
-
timestamp: string;
|
|
43
|
-
data?: Record<string, unknown>;
|
|
44
|
-
}
|
|
45
|
-
export interface TrackAgentOptions {
|
|
46
|
-
timeoutMs?: number;
|
|
47
|
-
maxRetries?: number;
|
|
48
|
-
expectedDeliverables?: string[];
|
|
49
|
-
parentAgentId?: string | null;
|
|
50
|
-
}
|
|
51
|
-
export interface RecoveryAction {
|
|
52
|
-
action: 'retry' | 'abandon' | 'notify';
|
|
53
|
-
reason: string;
|
|
54
|
-
agentId: string;
|
|
55
|
-
}
|
|
56
|
-
export interface GuaranteeData {
|
|
57
|
-
version: string;
|
|
58
|
-
config: AgentGuaranteeConfig;
|
|
59
|
-
history: AgentCompletionReport[];
|
|
60
|
-
updatedAt: string;
|
|
61
|
-
}
|
|
62
|
-
export interface GuaranteeAgentCompletionInput {
|
|
63
|
-
projectPath: string;
|
|
64
|
-
}
|
|
65
|
-
export interface AgentCompletionReportInput {
|
|
66
|
-
projectPath: string;
|
|
67
|
-
sessionId?: string;
|
|
68
|
-
}
|
|
69
|
-
export interface ConfigureAgentGuaranteesInput {
|
|
70
|
-
projectPath: string;
|
|
71
|
-
config: Partial<AgentGuaranteeConfig>;
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=agent-guarantees.d.ts.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/** A spec entry for CSV/sheet export. */
|
|
2
|
-
export interface SpecSheetEntry {
|
|
3
|
-
id: string;
|
|
4
|
-
title: string;
|
|
5
|
-
status: string;
|
|
6
|
-
estimate?: string;
|
|
7
|
-
risk?: string;
|
|
8
|
-
}
|
|
9
|
-
/** Result of a Google Workspace export operation. */
|
|
10
|
-
export interface GoogleWorkspaceExportResult {
|
|
11
|
-
/** Spec ID that was exported. */
|
|
12
|
-
specId: string;
|
|
13
|
-
/** Formatted content ready for Google Docs. */
|
|
14
|
-
formattedContent: string;
|
|
15
|
-
/** Google Apps Script for creating the Doc. */
|
|
16
|
-
appsScript: string;
|
|
17
|
-
}
|
|
18
|
-
/** Result of a Google Workspace sheet generation. */
|
|
19
|
-
export interface GoogleWorkspaceSheetResult {
|
|
20
|
-
/** CSV content ready for Google Sheets import. */
|
|
21
|
-
csv: string;
|
|
22
|
-
/** Number of specs included. */
|
|
23
|
-
specCount: number;
|
|
24
|
-
}
|
|
25
|
-
/** Result of a Google Workspace import operation. */
|
|
26
|
-
export interface GoogleWorkspaceImportResult {
|
|
27
|
-
/** Converted spec content. */
|
|
28
|
-
specContent: string;
|
|
29
|
-
/** Whether the import was successful. */
|
|
30
|
-
success: boolean;
|
|
31
|
-
}
|
|
32
|
-
/** Result of generating a Google Apps Script for live sync. */
|
|
33
|
-
export interface GoogleWorkspaceScriptResult {
|
|
34
|
-
/** Complete Apps Script code. */
|
|
35
|
-
script: string;
|
|
36
|
-
/** Instructions for setting up the script. */
|
|
37
|
-
instructions: string;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=google-workspace.d.ts.map
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/** The manifest returned by a /.well-known/mcp endpoint. */
|
|
2
|
-
export interface McpGatewayManifest {
|
|
3
|
-
name?: string;
|
|
4
|
-
version?: string;
|
|
5
|
-
tools?: string[];
|
|
6
|
-
resources?: string[];
|
|
7
|
-
planuCompatible?: boolean;
|
|
8
|
-
}
|
|
9
|
-
/** A gateway discovered (or previously known) via auto-discovery. */
|
|
10
|
-
export interface DiscoveredGateway {
|
|
11
|
-
url: string;
|
|
12
|
-
name: string;
|
|
13
|
-
discoveredAt: string;
|
|
14
|
-
lastSeenAt: string;
|
|
15
|
-
planuCompatible: boolean;
|
|
16
|
-
tools: string[];
|
|
17
|
-
status: 'active' | 'unreachable' | 'incompatible';
|
|
18
|
-
}
|
|
19
|
-
/** Persisted registry of all known gateways. */
|
|
20
|
-
export interface GatewayRegistry {
|
|
21
|
-
gateways: DiscoveredGateway[];
|
|
22
|
-
lastDiscoveryAt?: string;
|
|
23
|
-
}
|
|
24
|
-
/** Input for discover_mcp_gateways tool. */
|
|
25
|
-
export interface DiscoverMcpGatewaysInput {
|
|
26
|
-
projectPath: string;
|
|
27
|
-
urls?: string[];
|
|
28
|
-
includeLocalhost?: boolean;
|
|
29
|
-
}
|
|
30
|
-
/** Input for federation_discovery_status tool. */
|
|
31
|
-
export interface FederationDiscoveryStatusInput {
|
|
32
|
-
projectPath: string;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=mcp-gateway.d.ts.map
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export interface RefactorSession {
|
|
2
|
-
id: string;
|
|
3
|
-
sourceSpecId: string;
|
|
4
|
-
sourceProjectPath: string;
|
|
5
|
-
affectedSymbols: string[];
|
|
6
|
-
consumerProjects: ConsumerProject[];
|
|
7
|
-
startedAt: string;
|
|
8
|
-
status: 'scanning' | 'companion-specs-created' | 'in-progress' | 'completed';
|
|
9
|
-
}
|
|
10
|
-
export interface ConsumerProject {
|
|
11
|
-
projectPath: string;
|
|
12
|
-
projectId: string;
|
|
13
|
-
usageLocations: string[];
|
|
14
|
-
companionSpecId?: string;
|
|
15
|
-
status: 'pending' | 'spec-created' | 'implementing' | 'done';
|
|
16
|
-
}
|
|
17
|
-
export interface CoordinateRefactorInput {
|
|
18
|
-
projectPath: string;
|
|
19
|
-
specId: string;
|
|
20
|
-
affectedSymbols: string[];
|
|
21
|
-
}
|
|
22
|
-
export interface SyncRefactorStatusInput {
|
|
23
|
-
projectPath: string;
|
|
24
|
-
refactorId: string;
|
|
25
|
-
}
|
|
26
|
-
export interface RefactorRegistry {
|
|
27
|
-
sessions: RefactorSession[];
|
|
28
|
-
updatedAt: string;
|
|
29
|
-
}
|
|
30
|
-
export interface RefactorStatusReport {
|
|
31
|
-
refactorId: string;
|
|
32
|
-
sourceSpec: string;
|
|
33
|
-
totalConsumers: number;
|
|
34
|
-
completed: number;
|
|
35
|
-
inProgress: number;
|
|
36
|
-
pending: number;
|
|
37
|
-
overallProgress: number;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=multi-repo.d.ts.map
|
package/dist/types/multi-repo.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
// types/multi-repo.ts — SPEC-389: Multi-Repo Refactoring Coordination types
|
|
2
|
-
// NOTE: RefactorRegistry is an internal storage shape, kept here to satisfy the
|
|
3
|
-
// no-restricted-syntax rule that forbids type/interface declarations in src/storage/.
|
|
4
|
-
export {};
|
|
5
|
-
//# sourceMappingURL=multi-repo.js.map
|