@nepopsx/cli 0.0.23 → 0.0.25
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/commands/guard.d.ts +10 -0
- package/dist/commands/guard.d.ts.map +1 -0
- package/dist/commands/guard.js +63 -0
- package/dist/commands/guard.js.map +1 -0
- package/dist/commands/import-agents.d.ts +17 -0
- package/dist/commands/import-agents.d.ts.map +1 -0
- package/dist/commands/import-agents.js +166 -0
- package/dist/commands/import-agents.js.map +1 -0
- package/dist/commands/import.d.ts +19 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +175 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.js +4 -4
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +3 -3
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +26 -70
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/push-learnings.js +1 -1
- package/dist/commands/push-learnings.js.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +7 -2
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/up.js +2 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/config/api-config.d.ts +7 -0
- package/dist/config/api-config.d.ts.map +1 -1
- package/dist/config/api-config.js +9 -1
- package/dist/config/api-config.js.map +1 -1
- package/dist/config/global-config.d.ts +52 -0
- package/dist/config/global-config.d.ts.map +1 -0
- package/dist/config/global-config.js +161 -0
- package/dist/config/global-config.js.map +1 -0
- package/dist/config/global-config.test.d.ts +2 -0
- package/dist/config/global-config.test.d.ts.map +1 -0
- package/dist/config/global-config.test.js +62 -0
- package/dist/config/global-config.test.js.map +1 -0
- package/dist/guard/policy.d.ts +38 -0
- package/dist/guard/policy.d.ts.map +1 -0
- package/dist/guard/policy.js +62 -0
- package/dist/guard/policy.js.map +1 -0
- package/dist/guard/policy.test.d.ts +2 -0
- package/dist/guard/policy.test.d.ts.map +1 -0
- package/dist/guard/policy.test.js +47 -0
- package/dist/guard/policy.test.js.map +1 -0
- package/dist/hooks/capture-hooks.d.ts.map +1 -1
- package/dist/hooks/capture-hooks.js +36 -1
- package/dist/hooks/capture-hooks.js.map +1 -1
- package/dist/import/adapter.d.ts +82 -0
- package/dist/import/adapter.d.ts.map +1 -0
- package/dist/import/adapter.js +111 -0
- package/dist/import/adapter.js.map +1 -0
- package/dist/import/adapter.test.d.ts +2 -0
- package/dist/import/adapter.test.d.ts.map +1 -0
- package/dist/import/adapter.test.js +100 -0
- package/dist/import/adapter.test.js.map +1 -0
- package/dist/import/agents/agent-adapter.d.ts +83 -0
- package/dist/import/agents/agent-adapter.d.ts.map +1 -0
- package/dist/import/agents/agent-adapter.js +66 -0
- package/dist/import/agents/agent-adapter.js.map +1 -0
- package/dist/import/agents/agent-adapter.test.d.ts +2 -0
- package/dist/import/agents/agent-adapter.test.d.ts.map +1 -0
- package/dist/import/agents/agent-adapter.test.js +99 -0
- package/dist/import/agents/agent-adapter.test.js.map +1 -0
- package/dist/import/agents/artifact-parser.d.ts +26 -0
- package/dist/import/agents/artifact-parser.d.ts.map +1 -0
- package/dist/import/agents/artifact-parser.js +40 -0
- package/dist/import/agents/artifact-parser.js.map +1 -0
- package/dist/import/agents/assembler.d.ts +32 -0
- package/dist/import/agents/assembler.d.ts.map +1 -0
- package/dist/import/agents/assembler.js +62 -0
- package/dist/import/agents/assembler.js.map +1 -0
- package/dist/import/agents/assembler.test.d.ts +2 -0
- package/dist/import/agents/assembler.test.d.ts.map +1 -0
- package/dist/import/agents/assembler.test.js +115 -0
- package/dist/import/agents/assembler.test.js.map +1 -0
- package/dist/import/agents/claude-code-adapter.d.ts +11 -0
- package/dist/import/agents/claude-code-adapter.d.ts.map +1 -0
- package/dist/import/agents/claude-code-adapter.js +67 -0
- package/dist/import/agents/claude-code-adapter.js.map +1 -0
- package/dist/import/agents/copilot-agent-adapter.d.ts +12 -0
- package/dist/import/agents/copilot-agent-adapter.d.ts.map +1 -0
- package/dist/import/agents/copilot-agent-adapter.js +89 -0
- package/dist/import/agents/copilot-agent-adapter.js.map +1 -0
- package/dist/import/agents/scanner.d.ts +15 -0
- package/dist/import/agents/scanner.d.ts.map +1 -0
- package/dist/import/agents/scanner.js +87 -0
- package/dist/import/agents/scanner.js.map +1 -0
- package/dist/import/agents/secret-scan.d.ts +14 -0
- package/dist/import/agents/secret-scan.d.ts.map +1 -0
- package/dist/import/agents/secret-scan.js +64 -0
- package/dist/import/agents/secret-scan.js.map +1 -0
- package/dist/import/agents/secret-scan.test.d.ts +2 -0
- package/dist/import/agents/secret-scan.test.d.ts.map +1 -0
- package/dist/import/agents/secret-scan.test.js +41 -0
- package/dist/import/agents/secret-scan.test.js.map +1 -0
- package/dist/import/claude-memory-adapter.d.ts +20 -0
- package/dist/import/claude-memory-adapter.d.ts.map +1 -0
- package/dist/import/claude-memory-adapter.js +87 -0
- package/dist/import/claude-memory-adapter.js.map +1 -0
- package/dist/import/copilot-adapter.d.ts +13 -0
- package/dist/import/copilot-adapter.d.ts.map +1 -0
- package/dist/import/copilot-adapter.js +75 -0
- package/dist/import/copilot-adapter.js.map +1 -0
- package/dist/index.js +28 -7
- package/dist/index.js.map +1 -1
- package/dist/learnings/memory-index.d.ts +17 -0
- package/dist/learnings/memory-index.d.ts.map +1 -0
- package/dist/learnings/memory-index.js +73 -0
- package/dist/learnings/memory-index.js.map +1 -0
- package/dist/licensing/index.d.ts +1 -1
- package/dist/licensing/index.d.ts.map +1 -1
- package/dist/licensing/index.js +1 -1
- package/dist/licensing/index.js.map +1 -1
- package/dist/licensing/installer.d.ts +7 -8
- package/dist/licensing/installer.d.ts.map +1 -1
- package/dist/licensing/installer.js +9 -17
- package/dist/licensing/installer.js.map +1 -1
- package/dist/licensing/license-manager.d.ts +25 -51
- package/dist/licensing/license-manager.d.ts.map +1 -1
- package/dist/licensing/license-manager.js +54 -275
- package/dist/licensing/license-manager.js.map +1 -1
- package/dist/licensing/workspace-name.d.ts +1 -1
- package/dist/licensing/workspace-name.js +1 -1
- package/dist/mcp/config-generator.d.ts +6 -6
- package/dist/mcp/config-generator.d.ts.map +1 -1
- package/dist/mcp/config-generator.js +4 -4
- package/dist/mcp/config-generator.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nepopsx guard` — a Claude Code PreToolUse hook. Reads the tool call from stdin,
|
|
3
|
+
* evaluates it against the local policy, and emits a `permissionDecision: deny`
|
|
4
|
+
* (which blocks the call) when a rule matches. NO network on the hot path.
|
|
5
|
+
*
|
|
6
|
+
* SOFT-FAIL by design: any error in the guard itself exits cleanly (fail-open) so it
|
|
7
|
+
* can never crash or hang the calling session. Only an explicit rule match blocks.
|
|
8
|
+
*/
|
|
9
|
+
export declare function guardCommand(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/commands/guard.ts"],"names":[],"mappings":"AA0BA;;;;;;;GAOG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAgClD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { BUILTIN_RULES, evaluate, validRule } from '../guard/policy.js';
|
|
4
|
+
/** Read all of stdin (the hook payload). */
|
|
5
|
+
async function readStdin() {
|
|
6
|
+
const chunks = [];
|
|
7
|
+
for await (const chunk of process.stdin)
|
|
8
|
+
chunks.push(chunk);
|
|
9
|
+
return Buffer.concat(chunks).toString('utf-8');
|
|
10
|
+
}
|
|
11
|
+
/** Built-in rules + the locally-cached `.nepopsx/policy.json` (synced out-of-band). */
|
|
12
|
+
function loadRules(cwd) {
|
|
13
|
+
const rules = [...BUILTIN_RULES];
|
|
14
|
+
const policyPath = resolve(cwd, '.nepopsx', 'policy.json');
|
|
15
|
+
if (existsSync(policyPath)) {
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(readFileSync(policyPath, 'utf-8'));
|
|
18
|
+
if (Array.isArray(parsed.rules))
|
|
19
|
+
rules.push(...parsed.rules.filter(validRule));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
/* fail-open: a corrupt policy file must never break the session */
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return rules;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `nepopsx guard` — a Claude Code PreToolUse hook. Reads the tool call from stdin,
|
|
29
|
+
* evaluates it against the local policy, and emits a `permissionDecision: deny`
|
|
30
|
+
* (which blocks the call) when a rule matches. NO network on the hot path.
|
|
31
|
+
*
|
|
32
|
+
* SOFT-FAIL by design: any error in the guard itself exits cleanly (fail-open) so it
|
|
33
|
+
* can never crash or hang the calling session. Only an explicit rule match blocks.
|
|
34
|
+
*/
|
|
35
|
+
export async function guardCommand() {
|
|
36
|
+
try {
|
|
37
|
+
const raw = await readStdin();
|
|
38
|
+
if (!raw.trim())
|
|
39
|
+
return;
|
|
40
|
+
const payload = JSON.parse(raw);
|
|
41
|
+
const cwd = typeof payload.cwd === 'string' && payload.cwd ? payload.cwd : process.cwd();
|
|
42
|
+
const input = {
|
|
43
|
+
tool_name: typeof payload.tool_name === 'string' ? payload.tool_name : '',
|
|
44
|
+
tool_input: payload.tool_input ?? {},
|
|
45
|
+
};
|
|
46
|
+
const verdict = evaluate(input, loadRules(cwd));
|
|
47
|
+
if (verdict.decision === 'deny' && verdict.rule) {
|
|
48
|
+
// permissionDecision:deny blocks the tool call; the reason is shown to the agent.
|
|
49
|
+
process.stdout.write(`${JSON.stringify({
|
|
50
|
+
hookSpecificOutput: {
|
|
51
|
+
hookEventName: 'PreToolUse',
|
|
52
|
+
permissionDecision: 'deny',
|
|
53
|
+
permissionDecisionReason: `[nepopsx policy:${verdict.rule.id}] ${verdict.rule.reason}`,
|
|
54
|
+
},
|
|
55
|
+
})}\n`);
|
|
56
|
+
}
|
|
57
|
+
// allow → no output, exit 0
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* fail-open */
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/commands/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAoC,MAAM,oBAAoB,CAAC;AAE1G,4CAA4C;AAC5C,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,uFAAuF;AACvF,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA0B,CAAC;YACtF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACjF,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,OAAO;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAI7B,CAAC;QACF,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACzF,MAAM,KAAK,GAAe;YACxB,SAAS,EAAE,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE;YACzE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE;SACrC,CAAC;QAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAChD,kFAAkF;YAClF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;gBAChB,kBAAkB,EAAE;oBAClB,aAAa,EAAE,YAAY;oBAC3B,kBAAkB,EAAE,MAAM;oBAC1B,wBAAwB,EAAE,mBAAmB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE;iBACvF;aACF,CAAC,IAAI,CACP,CAAC;QACJ,CAAC;QACD,4BAA4B;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface ImportAgentsOptions {
|
|
2
|
+
config: string;
|
|
3
|
+
workspace?: string;
|
|
4
|
+
dryRun?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `nepopsx import-agents` — comprehend a customer's existing custom agents
|
|
8
|
+
* (.claude/agents, .github/agents) into the platform as governed PENDING bundles.
|
|
9
|
+
*
|
|
10
|
+
* Scans both ecosystems, assembles agent-centric bundles (orchestration graph +
|
|
11
|
+
* dangling-ref flags), redacts secrets locally, then POSTs in size-bounded batches to
|
|
12
|
+
* /agents/import. Foreign agents are untrusted: every bundle lands PENDING (or
|
|
13
|
+
* QUARANTINED on a security-scan hit) for review — never auto-blessed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function importAgentsCommand(options: ImportAgentsOptions): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=import-agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-agents.d.ts","sourceRoot":"","sources":["../../src/commands/import-agents.ts"],"names":[],"mappings":"AAYA,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAqED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FrF"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { parse as parseYaml } from 'yaml';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { resolveApiBase } from '../config/api-config.js';
|
|
6
|
+
import { readLicense, resolveWorkspaceName } from '../licensing/index.js';
|
|
7
|
+
import { fetchWithTimeout } from '../utils/fetch.js';
|
|
8
|
+
import { DOWNLOAD_TIMEOUT_MS } from '../constants.js';
|
|
9
|
+
import { scanRepo } from '../import/agents/scanner.js';
|
|
10
|
+
import { assembleBundles } from '../import/agents/assembler.js';
|
|
11
|
+
import { redactSecrets, redactValue } from '../import/agents/secret-scan.js';
|
|
12
|
+
/** Conservative per-request budget — the /agents/import body limit 413s on big repos. */
|
|
13
|
+
const MAX_REQUEST_BYTES = 60_000;
|
|
14
|
+
/** Serialize one assembled bundle into the import payload, redacting secrets first. */
|
|
15
|
+
function toPayload(b) {
|
|
16
|
+
const inst = redactSecrets(b.agent.instructions);
|
|
17
|
+
const rawR = redactSecrets(b.agent.raw);
|
|
18
|
+
const extraR = redactValue(b.agent.extra);
|
|
19
|
+
const redactions = inst.count + rawR.count + extraR.count;
|
|
20
|
+
const fidelity = [
|
|
21
|
+
...b.fidelity,
|
|
22
|
+
...b.agent.fidelity,
|
|
23
|
+
...(redactions > 0
|
|
24
|
+
? [{ field: 'secrets', severity: 'loss', detail: `Redacted ${redactions} secret(s) before import.` }]
|
|
25
|
+
: []),
|
|
26
|
+
];
|
|
27
|
+
return {
|
|
28
|
+
redactions,
|
|
29
|
+
payload: {
|
|
30
|
+
slug: b.agent.slug,
|
|
31
|
+
name: b.agent.name,
|
|
32
|
+
kind: b.agent.kind,
|
|
33
|
+
description: b.agent.description,
|
|
34
|
+
originProvider: b.agent.originProvider,
|
|
35
|
+
instructions: inst.value,
|
|
36
|
+
importedFrom: b.agent.importedFrom,
|
|
37
|
+
fidelity,
|
|
38
|
+
ir: {
|
|
39
|
+
agent: {
|
|
40
|
+
modelRaw: b.agent.modelRaw,
|
|
41
|
+
tools: b.agent.tools,
|
|
42
|
+
disallowedTools: b.agent.disallowedTools,
|
|
43
|
+
subAgents: b.agent.subAgents,
|
|
44
|
+
handoffs: b.agent.handoffs,
|
|
45
|
+
userInvocable: b.agent.userInvocable,
|
|
46
|
+
target: b.agent.target,
|
|
47
|
+
extra: extraR.value,
|
|
48
|
+
raw: rawR.value,
|
|
49
|
+
},
|
|
50
|
+
graph: b.graph,
|
|
51
|
+
skills: b.skills.map((s) => s.slug),
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Greedily batch payloads so each POST body stays under the size limit (413 fix). */
|
|
57
|
+
function chunkByBytes(items, maxBytes) {
|
|
58
|
+
const out = [];
|
|
59
|
+
let cur = [];
|
|
60
|
+
let size = 2; // "[]"
|
|
61
|
+
for (const it of items) {
|
|
62
|
+
const s = JSON.stringify(it).length + 1;
|
|
63
|
+
if (cur.length > 0 && size + s > maxBytes) {
|
|
64
|
+
out.push(cur);
|
|
65
|
+
cur = [];
|
|
66
|
+
size = 2;
|
|
67
|
+
}
|
|
68
|
+
cur.push(it);
|
|
69
|
+
size += s;
|
|
70
|
+
}
|
|
71
|
+
if (cur.length > 0)
|
|
72
|
+
out.push(cur);
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `nepopsx import-agents` — comprehend a customer's existing custom agents
|
|
77
|
+
* (.claude/agents, .github/agents) into the platform as governed PENDING bundles.
|
|
78
|
+
*
|
|
79
|
+
* Scans both ecosystems, assembles agent-centric bundles (orchestration graph +
|
|
80
|
+
* dangling-ref flags), redacts secrets locally, then POSTs in size-bounded batches to
|
|
81
|
+
* /agents/import. Foreign agents are untrusted: every bundle lands PENDING (or
|
|
82
|
+
* QUARANTINED on a security-scan hit) for review — never auto-blessed.
|
|
83
|
+
*/
|
|
84
|
+
export async function importAgentsCommand(options) {
|
|
85
|
+
const cwd = process.cwd();
|
|
86
|
+
let config = {};
|
|
87
|
+
const configPath = resolve(cwd, options.config);
|
|
88
|
+
if (existsSync(configPath)) {
|
|
89
|
+
try {
|
|
90
|
+
const raw = parseYaml(readFileSync(configPath, 'utf-8'));
|
|
91
|
+
if (raw && typeof raw === 'object')
|
|
92
|
+
config = raw;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
/* best-effort */
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const bundles = assembleBundles(scanRepo(cwd));
|
|
99
|
+
if (bundles.length === 0) {
|
|
100
|
+
console.log(chalk.dim('nepopsx import-agents: no agents found under .claude/agents or .github/agents.'));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const serialized = bundles.map(toPayload);
|
|
104
|
+
const totalRedactions = serialized.reduce((n, s) => n + s.redactions, 0);
|
|
105
|
+
const dangling = bundles.reduce((n, b) => n + b.graph.filter((e) => !e.resolvedInSet).length, 0);
|
|
106
|
+
// ── Dry run: report locally, no auth, no POST ──────────────────────────────
|
|
107
|
+
if (options.dryRun) {
|
|
108
|
+
console.log(chalk.bold.cyan(`\n🔎 nepopsx import-agents — dry run (${bundles.length} bundle(s))\n`));
|
|
109
|
+
for (const b of bundles) {
|
|
110
|
+
const tag = b.agent.kind === 'command' ? chalk.magenta('orchestrator') : chalk.dim('agent');
|
|
111
|
+
const edges = b.graph.length ? ` graph[${b.graph.map((e) => e.to + (e.resolvedInSet ? '' : ' ✗')).join(', ')}]` : '';
|
|
112
|
+
console.log(` ${chalk.bold(b.agent.slug)} ${tag} ${chalk.dim(`[${b.agent.originProvider}]`)}${edges}`);
|
|
113
|
+
console.log(` ${chalk.dim(b.agent.importedFrom)}`);
|
|
114
|
+
}
|
|
115
|
+
const batches = chunkByBytes(serialized.map((s) => s.payload), MAX_REQUEST_BYTES);
|
|
116
|
+
console.log(chalk.dim(`\n ${totalRedactions} secret(s) would be redacted · ${dangling} dangling ref(s) · ${batches.length} batch(es).`));
|
|
117
|
+
console.log(chalk.dim(' No changes sent. Re-run without --dry-run to import as PENDING for review.\n'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// ── Real run: auth + workspace, then POST in batches ───────────────────────
|
|
121
|
+
const license = readLicense(cwd);
|
|
122
|
+
if (!license) {
|
|
123
|
+
console.error(chalk.red('nepopsx import-agents: not logged in. Run `nepopsx login` first.'));
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const workspace = options.workspace ?? resolveWorkspaceName(cwd, license, config);
|
|
128
|
+
if (!workspace || workspace === 'unknown') {
|
|
129
|
+
console.error(chalk.red('nepopsx import-agents: could not resolve a workspace. Pass --workspace.'));
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const apiBase = resolveApiBase(cwd);
|
|
134
|
+
const batches = chunkByBytes(serialized.map((s) => s.payload), MAX_REQUEST_BYTES);
|
|
135
|
+
let received = 0;
|
|
136
|
+
let pending = 0;
|
|
137
|
+
let quarantined = 0;
|
|
138
|
+
try {
|
|
139
|
+
for (const [i, batch] of batches.entries()) {
|
|
140
|
+
const response = await fetchWithTimeout(`${apiBase}/agents/import`, {
|
|
141
|
+
method: 'POST',
|
|
142
|
+
headers: { Authorization: `Bearer ${license.key}`, 'Content-Type': 'application/json' },
|
|
143
|
+
body: JSON.stringify({ workspace, bundles: batch }),
|
|
144
|
+
}, DOWNLOAD_TIMEOUT_MS);
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
const body = await response.text().catch(() => '');
|
|
147
|
+
console.error(chalk.red(`nepopsx import-agents: batch ${i + 1}/${batches.length} → ${response.status} ${body.slice(0, 200)}`));
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const json = (await response.json());
|
|
152
|
+
received += json.received ?? 0;
|
|
153
|
+
pending += json.pending ?? 0;
|
|
154
|
+
quarantined += json.quarantined ?? 0;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
console.error(chalk.red(`nepopsx import-agents: failed — ${err instanceof Error ? err.message : String(err)}`));
|
|
159
|
+
process.exitCode = 1;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
console.log(chalk.green(`\n✅ nepopsx import-agents: ${received} imported → ${pending} pending, ${quarantined} quarantined ` +
|
|
163
|
+
`(${totalRedactions} secret(s) redacted, ${batches.length} batch(es)).`));
|
|
164
|
+
console.log(chalk.dim(' Review pending agents in the dashboard before they render.'));
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=import-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-agents.js","sourceRoot":"","sources":["../../src/commands/import-agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface ImportOptions {
|
|
2
|
+
config: string;
|
|
3
|
+
workspace?: string;
|
|
4
|
+
source: string;
|
|
5
|
+
agent?: string;
|
|
6
|
+
dryRun?: boolean;
|
|
7
|
+
force?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* `nepopsx import` — ingest agent-memory files written by OTHER tools (GitHub
|
|
11
|
+
* Copilot instructions, Claude project memory) into the platform as PENDING
|
|
12
|
+
* learnings, routed to the resolved org/workspace and scoped by service.
|
|
13
|
+
*
|
|
14
|
+
* Governance: every imported learning is sent with frequency=1 so it can never
|
|
15
|
+
* auto-approve — it always lands in the review queue. Foreign memory is untrusted.
|
|
16
|
+
*/
|
|
17
|
+
export declare function importCommand(options: ImportOptions): Promise<void>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"AAeA,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAeD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAuLzE"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { parse as parseYaml } from 'yaml';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { resolveApiBase } from '../config/api-config.js';
|
|
6
|
+
import { readLicense, resolveWorkspaceName } from '../licensing/index.js';
|
|
7
|
+
import { fetchWithTimeout } from '../utils/fetch.js';
|
|
8
|
+
import { DOWNLOAD_TIMEOUT_MS } from '../constants.js';
|
|
9
|
+
import { writeYamlLearning } from '../learnings/yaml-learnings.js';
|
|
10
|
+
import { regenerateMemoryIndex } from '../learnings/memory-index.js';
|
|
11
|
+
import { copilotAdapter } from '../import/copilot-adapter.js';
|
|
12
|
+
import { claudeMemoryAdapter } from '../import/claude-memory-adapter.js';
|
|
13
|
+
const ADAPTERS = [copilotAdapter, claudeMemoryAdapter];
|
|
14
|
+
/** Map an adapter's source tag to the constrained LearningYaml.source union. */
|
|
15
|
+
function provenanceSource(adapterId) {
|
|
16
|
+
return adapterId === 'claude-memory' ? 'claude-auto-memory' : 'manual';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* `nepopsx import` — ingest agent-memory files written by OTHER tools (GitHub
|
|
20
|
+
* Copilot instructions, Claude project memory) into the platform as PENDING
|
|
21
|
+
* learnings, routed to the resolved org/workspace and scoped by service.
|
|
22
|
+
*
|
|
23
|
+
* Governance: every imported learning is sent with frequency=1 so it can never
|
|
24
|
+
* auto-approve — it always lands in the review queue. Foreign memory is untrusted.
|
|
25
|
+
*/
|
|
26
|
+
export async function importCommand(options) {
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
// Load workspace config (services for scope inference + workspace name).
|
|
29
|
+
let config = {};
|
|
30
|
+
const configPath = resolve(cwd, options.config);
|
|
31
|
+
if (existsSync(configPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const raw = parseYaml(readFileSync(configPath, 'utf-8'));
|
|
34
|
+
if (raw && typeof raw === 'object')
|
|
35
|
+
config = raw;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
/* best-effort */
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const services = Array.isArray(config.services)
|
|
42
|
+
? config.services
|
|
43
|
+
.filter((s) => typeof s?.name === 'string')
|
|
44
|
+
.map((s) => ({ name: s.name, path: s.path }))
|
|
45
|
+
: [];
|
|
46
|
+
const ctx = { rootDir: cwd, services };
|
|
47
|
+
// Select adapters.
|
|
48
|
+
const wanted = options.source === 'all' ? ADAPTERS.map((a) => a.id) : [options.source];
|
|
49
|
+
const selected = ADAPTERS.filter((a) => wanted.includes(a.id));
|
|
50
|
+
if (selected.length === 0) {
|
|
51
|
+
console.error(chalk.red(`Unknown --source "${options.source}". Use: copilot | claude-memory | all.`));
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Parse all candidates.
|
|
56
|
+
const importedDir = resolve(cwd, '.nepopsx', 'imported');
|
|
57
|
+
const candidates = [];
|
|
58
|
+
let skippedExisting = 0;
|
|
59
|
+
for (const adapter of selected) {
|
|
60
|
+
const agent = options.agent ?? adapter.id;
|
|
61
|
+
const files = adapter.detect(ctx);
|
|
62
|
+
for (const file of files) {
|
|
63
|
+
for (const raw of adapter.parse(file, ctx)) {
|
|
64
|
+
// Idempotency: skip a candidate already imported (unless --force).
|
|
65
|
+
const marker = resolve(importedDir, adapter.id, `${raw.slug}.yaml`);
|
|
66
|
+
if (!options.force && existsSync(marker)) {
|
|
67
|
+
skippedExisting++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
candidates.push({ adapterId: adapter.id, agent, raw });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (candidates.length === 0) {
|
|
75
|
+
console.log(chalk.dim(`nepopsx import: nothing new to import` +
|
|
76
|
+
(skippedExisting > 0 ? ` (${skippedExisting} already imported — use --force to re-import).` : '.')));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// ── Dry run: report and exit, no POST ──────────────────────────────────────
|
|
80
|
+
if (options.dryRun) {
|
|
81
|
+
console.log(chalk.bold.cyan(`\n🔎 nepopsx import — dry run (${candidates.length} candidate(s))\n`));
|
|
82
|
+
for (const c of candidates) {
|
|
83
|
+
const scope = c.raw.services && c.raw.services.length > 0 ? c.raw.services.join(', ') : 'workspace-wide';
|
|
84
|
+
console.log(` ${chalk.bold(c.raw.slug)} ${chalk.dim(`[${c.adapterId} → ${scope}]`)}`);
|
|
85
|
+
console.log(` ${chalk.dim(c.raw.importedFrom)}`);
|
|
86
|
+
}
|
|
87
|
+
if (skippedExisting > 0) {
|
|
88
|
+
console.log(chalk.dim(`\n (${skippedExisting} already imported; skipped.)`));
|
|
89
|
+
}
|
|
90
|
+
console.log(chalk.dim('\n No changes written. Re-run without --dry-run to import as pending.\n'));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// ── Real run: require auth + a resolved org/workspace ───────────────────────
|
|
94
|
+
const license = readLicense(cwd);
|
|
95
|
+
if (!license) {
|
|
96
|
+
console.error(chalk.red('nepopsx import: not logged in. Run `nepopsx login` first.'));
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const workspace = options.workspace ?? resolveWorkspaceName(cwd, license, config);
|
|
101
|
+
if (!workspace || workspace === 'unknown') {
|
|
102
|
+
console.error(chalk.red('nepopsx import: could not resolve a workspace. Set workspace.name in workspace.yaml or pass --workspace.'));
|
|
103
|
+
process.exitCode = 1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!license.org) {
|
|
107
|
+
console.error(chalk.red('nepopsx import: could not resolve an org for this project. Run `nepopsx login` here, ' +
|
|
108
|
+
'or pin the org in workspace.yaml.'));
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const namespace = `${license.org}/${workspace}`;
|
|
113
|
+
const apiBase = resolveApiBase(cwd);
|
|
114
|
+
// frequency=1 ⇒ low confidence ⇒ backend lands it PENDING (never auto-approved).
|
|
115
|
+
const patterns = candidates.map((c) => ({
|
|
116
|
+
type: c.raw.type ?? 'custom_instruction',
|
|
117
|
+
slug: c.raw.slug,
|
|
118
|
+
title: c.raw.title,
|
|
119
|
+
content: c.raw.content,
|
|
120
|
+
agent: c.agent,
|
|
121
|
+
applies_to: c.raw.appliesTo ?? [],
|
|
122
|
+
services: c.raw.services ?? [],
|
|
123
|
+
source: c.raw.source,
|
|
124
|
+
frequency: 1,
|
|
125
|
+
config_path: c.raw.configPath,
|
|
126
|
+
config_value: c.raw.configValue,
|
|
127
|
+
}));
|
|
128
|
+
let results = [];
|
|
129
|
+
try {
|
|
130
|
+
const response = await fetchWithTimeout(`${apiBase}/learnings/auto`, {
|
|
131
|
+
method: 'POST',
|
|
132
|
+
headers: { Authorization: `Bearer ${license.key}`, 'Content-Type': 'application/json' },
|
|
133
|
+
body: JSON.stringify({ workspace, namespace, patterns }),
|
|
134
|
+
}, DOWNLOAD_TIMEOUT_MS);
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
const body = await response.text().catch(() => '');
|
|
137
|
+
console.error(chalk.red(`nepopsx import: backend ${response.status} — ${body.slice(0, 200)}`));
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const json = (await response.json());
|
|
142
|
+
results = json.results ?? [];
|
|
143
|
+
// Write provenance YAML per candidate, stamped with the server's verdict.
|
|
144
|
+
const verdictBySlug = new Map(results.map((r) => [r.slug, r.status]));
|
|
145
|
+
for (const c of candidates) {
|
|
146
|
+
const status = verdictBySlug.get(c.raw.slug);
|
|
147
|
+
const yaml = {
|
|
148
|
+
slug: c.raw.slug,
|
|
149
|
+
type: (c.raw.type ?? 'custom_instruction'),
|
|
150
|
+
confidence: 'low',
|
|
151
|
+
agent: c.agent,
|
|
152
|
+
applies_to: c.raw.appliesTo ?? [],
|
|
153
|
+
services: c.raw.services ?? [],
|
|
154
|
+
status: status === 'rejected' ? 'reverted' : status === 'approved' ? 'approved' : 'pending',
|
|
155
|
+
content: c.raw.content,
|
|
156
|
+
evidence: `Imported from ${c.raw.importedFrom} via ${c.raw.source}`,
|
|
157
|
+
source: provenanceSource(c.adapterId),
|
|
158
|
+
created_at: new Date().toISOString(),
|
|
159
|
+
};
|
|
160
|
+
writeYamlLearning(resolve(importedDir, c.adapterId), yaml);
|
|
161
|
+
}
|
|
162
|
+
console.log(chalk.green(`\n✅ nepopsx import: ${json.received ?? patterns.length} imported → ` +
|
|
163
|
+
`${json.pending ?? 0} pending, ${json.auto_applied ?? 0} applied, ${json.rejected ?? 0} rejected (scanned).`));
|
|
164
|
+
console.log(chalk.dim(' Review pending imports in the dashboard, or `nepopsx sync` once approved.'));
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
console.error(chalk.red(`nepopsx import: failed — ${err instanceof Error ? err.message : String(err)}`));
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
// Refresh the human-scannable index.
|
|
172
|
+
const index = regenerateMemoryIndex(cwd);
|
|
173
|
+
console.log(chalk.dim(` MEMORY.md updated (${index.count} learnings indexed).\n`));
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/commands/import.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAaA,UAAU,WAAW;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAaA,UAAU,WAAW;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA+ND,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8JrE"}
|
package/dist/commands/init.js
CHANGED
|
@@ -10,15 +10,23 @@ import { resolveApiBase } from '../config/api-config.js';
|
|
|
10
10
|
import { API_TIMEOUT_MS, DOWNLOAD_TIMEOUT_MS } from '../constants.js';
|
|
11
11
|
import { fetchEntitledAgents } from '../agents/catalog.js';
|
|
12
12
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Ensure the repo `.gitignore` ignores `.nepopsx/config.json`. The device token
|
|
15
|
+
* lives in `~/.nepopsx` now, but this guards any pre-migration leftover and the
|
|
16
|
+
* non-secret local config from being committed. Best-effort.
|
|
17
|
+
*/
|
|
18
|
+
function ensureGitignoreGuard(rootDir) {
|
|
19
|
+
const guard = '.nepopsx/config.json';
|
|
20
|
+
const gitignorePath = join(rootDir, '.gitignore');
|
|
17
21
|
try {
|
|
18
|
-
|
|
22
|
+
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';
|
|
23
|
+
if (existing.split(/\r?\n/).some((line) => line.trim() === guard))
|
|
24
|
+
return;
|
|
25
|
+
const prefix = existing.length > 0 && !existing.endsWith('\n') ? '\n' : '';
|
|
26
|
+
writeFileSync(gitignorePath, `${existing}${prefix}# nepopsx — never commit credentials\n${guard}\n`, 'utf-8');
|
|
19
27
|
}
|
|
20
28
|
catch {
|
|
21
|
-
|
|
29
|
+
/* best-effort */
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
async function tryListRemoteWorkspaces(cwd, licenseKey) {
|
|
@@ -143,7 +151,7 @@ function printNextSteps(scenario, extra) {
|
|
|
143
151
|
console.log(` 2. Enrich repo: ${chalk.cyan('nepopsx scan')}`);
|
|
144
152
|
console.log(` 3. Install agent: ${chalk.cyan('nepopsx install feature-factory')}`);
|
|
145
153
|
console.log(` 4. Generate files: ${chalk.cyan('nepopsx sync')}`);
|
|
146
|
-
console.log(` 5. Share with team: Run ${chalk.cyan('nepopsx
|
|
154
|
+
console.log(` 5. Share with team: Run ${chalk.cyan('nepopsx login')} and then run ${chalk.cyan('nepopsx init')} again`);
|
|
147
155
|
break;
|
|
148
156
|
case 'pushed-team':
|
|
149
157
|
console.log(` 1. Review config: ${chalk.cyan('cat .nepopsx/workspace.yaml')}`);
|
|
@@ -162,8 +170,8 @@ function printNextSteps(scenario, extra) {
|
|
|
162
170
|
break;
|
|
163
171
|
case 'local-no-license':
|
|
164
172
|
console.log(` 1. Review config: ${chalk.cyan('cat .nepopsx/workspace.yaml')}`);
|
|
165
|
-
console.log(` 2.
|
|
166
|
-
console.log(` 3.
|
|
173
|
+
console.log(` 2. Choose a plan: ${chalk.cyan('https://nepopsx.dev/pricing')}`);
|
|
174
|
+
console.log(` 3. Connect machine:${chalk.cyan('nepopsx login')}`);
|
|
167
175
|
console.log(` 4. Enrich repo: ${chalk.cyan('nepopsx scan')}`);
|
|
168
176
|
console.log(` 5. Install agent: ${chalk.cyan('nepopsx install feature-factory')}`);
|
|
169
177
|
console.log(` 6. Generate files: ${chalk.cyan('nepopsx sync')}`);
|
|
@@ -200,12 +208,12 @@ export async function initCommand(options) {
|
|
|
200
208
|
console.log(chalk.bold.cyan('\n🔧 NEPOPSX Workspace Setup\n'));
|
|
201
209
|
// ── Probe auth state ──────────────────────────────────────────────────────
|
|
202
210
|
const license = readLicense(cwd);
|
|
203
|
-
const
|
|
204
|
-
const orgSlug = storedConfig.auth?.org;
|
|
211
|
+
const orgSlug = license?.org || undefined;
|
|
205
212
|
const apiBase = resolveApiBase(cwd);
|
|
213
|
+
ensureGitignoreGuard(cwd);
|
|
206
214
|
if (!license) {
|
|
207
215
|
// ── No license: local-only setup ────────────────────────────────────────
|
|
208
|
-
console.warn(chalk.yellow('⚠
|
|
216
|
+
console.warn(chalk.yellow('⚠ Not logged in — run `nepopsx login` to sync with your team.'));
|
|
209
217
|
console.log(chalk.dim(' Workspace will be set up locally (personal use only).\n'));
|
|
210
218
|
const choice = await select({
|
|
211
219
|
message: 'How do you want to proceed?',
|
|
@@ -216,8 +224,8 @@ export async function initCommand(options) {
|
|
|
216
224
|
});
|
|
217
225
|
if (choice === 'license') {
|
|
218
226
|
console.log('');
|
|
219
|
-
console.log(` 1. Visit ${chalk.cyan('https://nepopsx.dev/pricing')} to
|
|
220
|
-
console.log(` 2. Run ${chalk.cyan('nepopsx
|
|
227
|
+
console.log(` 1. Visit ${chalk.cyan('https://nepopsx.dev/pricing')} to choose a plan`);
|
|
228
|
+
console.log(` 2. Run ${chalk.cyan('nepopsx login')} to connect this machine`);
|
|
221
229
|
console.log(` 3. Re-run ${chalk.cyan('nepopsx init')} to configure your workspace\n`);
|
|
222
230
|
return;
|
|
223
231
|
}
|