@coralai/sps-cli 0.90.0 → 0.90.2

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.
Files changed (78) hide show
  1. package/assembly/base.yml +4 -4
  2. package/dist/console/index.d.ts.map +1 -1
  3. package/dist/console/index.js +0 -2
  4. package/dist/console/index.js.map +1 -1
  5. package/dist/core/agents/ClaudeSdkBackend.d.ts +9 -0
  6. package/dist/core/agents/ClaudeSdkBackend.d.ts.map +1 -1
  7. package/dist/core/agents/ClaudeSdkBackend.js +5 -0
  8. package/dist/core/agents/ClaudeSdkBackend.js.map +1 -1
  9. package/dist/core/pathFence.d.ts +14 -14
  10. package/dist/core/pathFence.d.ts.map +1 -1
  11. package/dist/core/pathFence.js +11 -51
  12. package/dist/core/pathFence.js.map +1 -1
  13. package/dist/daemon/sessionDaemon.d.ts +16 -3
  14. package/dist/daemon/sessionDaemon.d.ts.map +1 -1
  15. package/dist/daemon/sessionDaemon.js +16 -7
  16. package/dist/daemon/sessionDaemon.js.map +1 -1
  17. package/dist/seams/agents-builtin/index.d.ts.map +1 -1
  18. package/dist/seams/agents-builtin/index.js +66 -51
  19. package/dist/seams/agents-builtin/index.js.map +1 -1
  20. package/dist/seams/memory/index.d.ts +8 -0
  21. package/dist/seams/memory/index.d.ts.map +1 -1
  22. package/dist/seams/memory/index.js +10 -0
  23. package/dist/seams/memory/index.js.map +1 -1
  24. package/dist/seams/memory/optional.d.ts +5 -0
  25. package/dist/seams/memory/optional.d.ts.map +1 -1
  26. package/dist/seams/memory/optional.js +7 -1
  27. package/dist/seams/memory/optional.js.map +1 -1
  28. package/dist/seams/workspace/index.d.ts +40 -0
  29. package/dist/seams/workspace/index.d.ts.map +1 -0
  30. package/dist/seams/workspace/index.js +46 -0
  31. package/dist/seams/workspace/index.js.map +1 -0
  32. package/docs/help/02-commands.md +2 -2
  33. package/docs/help/05-api.md +2 -12
  34. package/package.json +2 -2
  35. package/dist/console/routes/storage.d.ts +0 -21
  36. package/dist/console/routes/storage.d.ts.map +0 -1
  37. package/dist/console/routes/storage.js +0 -115
  38. package/dist/console/routes/storage.js.map +0 -1
  39. package/dist/daemon/storageSyncLoop.d.ts +0 -9
  40. package/dist/daemon/storageSyncLoop.d.ts.map +0 -1
  41. package/dist/daemon/storageSyncLoop.js +0 -70
  42. package/dist/daemon/storageSyncLoop.js.map +0 -1
  43. package/dist/providers/storage/FakeStorage.d.ts +0 -16
  44. package/dist/providers/storage/FakeStorage.d.ts.map +0 -1
  45. package/dist/providers/storage/FakeStorage.js +0 -37
  46. package/dist/providers/storage/FakeStorage.js.map +0 -1
  47. package/dist/providers/storage/MinioBackend.d.ts +0 -41
  48. package/dist/providers/storage/MinioBackend.d.ts.map +0 -1
  49. package/dist/providers/storage/MinioBackend.js +0 -85
  50. package/dist/providers/storage/MinioBackend.js.map +0 -1
  51. package/dist/providers/storage/StorageBackend.d.ts +0 -52
  52. package/dist/providers/storage/StorageBackend.d.ts.map +0 -1
  53. package/dist/providers/storage/StorageBackend.js +0 -29
  54. package/dist/providers/storage/StorageBackend.js.map +0 -1
  55. package/dist/providers/storage/keys.d.ts +0 -33
  56. package/dist/providers/storage/keys.d.ts.map +0 -1
  57. package/dist/providers/storage/keys.js +0 -52
  58. package/dist/providers/storage/keys.js.map +0 -1
  59. package/dist/providers/storage/storageConfig.d.ts +0 -46
  60. package/dist/providers/storage/storageConfig.d.ts.map +0 -1
  61. package/dist/providers/storage/storageConfig.js +0 -94
  62. package/dist/providers/storage/storageConfig.js.map +0 -1
  63. package/dist/providers/storage/syncProject.d.ts +0 -67
  64. package/dist/providers/storage/syncProject.d.ts.map +0 -1
  65. package/dist/providers/storage/syncProject.js +0 -136
  66. package/dist/providers/storage/syncProject.js.map +0 -1
  67. package/dist/providers/storage/syncRunner.d.ts +0 -59
  68. package/dist/providers/storage/syncRunner.d.ts.map +0 -1
  69. package/dist/providers/storage/syncRunner.js +0 -119
  70. package/dist/providers/storage/syncRunner.js.map +0 -1
  71. package/dist/providers/storage/syncable.d.ts +0 -47
  72. package/dist/providers/storage/syncable.d.ts.map +0 -1
  73. package/dist/providers/storage/syncable.js +0 -84
  74. package/dist/providers/storage/syncable.js.map +0 -1
  75. package/dist/seams/storage/index.d.ts +0 -53
  76. package/dist/seams/storage/index.d.ts.map +0 -1
  77. package/dist/seams/storage/index.js +0 -69
  78. package/dist/seams/storage/index.js.map +0 -1
@@ -2,69 +2,84 @@ import { ClaudeSdkBackend } from '../../core/agents/ClaudeSdkBackend.js';
2
2
  import { DaemonBackend } from '../../core/agents/DaemonBackend.js';
3
3
  import { OpenAiAgentBackend } from '../../core/agents/OpenAiAgentBackend.js';
4
4
  import { AGENTS } from '../agents/index.js';
5
+ import { memoryOf } from '../memory/optional.js';
5
6
  /** 插件页展示用。**由插件自己声明** —— 前端写死的表对第三方永远是空的。 */
6
7
  export const category = 'Agent 后端';
7
8
  export const description = '内建四个后端:claude-sdk / claude-daemon / openai-sdk / openai-daemon。';
8
- const BUILTIN = [
9
- {
10
- id: 'claude-daemon',
11
- summary: '人才市场:委托共享 daemon(与 chat 同宿主,统一并发/监控)',
12
- create: (ctx) => new DaemonBackend({
13
- backend: 'claude',
14
- sessionName: ctx.sessionName,
15
- cwd: ctx.cwd,
16
- project: ctx.project,
17
- resumeSessionId: ctx.resumeSessionId,
18
- extraEnv: ctx.extraEnv,
19
- }),
20
- },
21
- {
22
- id: 'openai-daemon',
23
- summary: 'openai/codex 走共享 daemon;provider 传输按 providerId 推导',
24
- create: (ctx) => {
25
- const providerId = ctx.providerId ?? 'official';
26
- const transport = ctx.providerTransport ??
27
- (providerId === 'codex'
28
- ? 'codex'
29
- : providerId === 'official'
30
- ? 'responses'
31
- : 'chat_completions');
32
- return new DaemonBackend({
33
- backend: 'openai',
9
+ /**
10
+ * 🔴 收 `host`(Cordis ctx)而不是模块级常量:`claude-sdk` 要问 `sps.memory`
11
+ * 有没有自带的 claude 插件目录,而 `BackendCtx` 里没有装配上下文 ——
12
+ * 加到 `BackendCtx` 上会把一个 claude 专属的需要摊给所有后端。
13
+ */
14
+ function builtins(host) {
15
+ return [
16
+ {
17
+ id: 'claude-daemon',
18
+ summary: '人才市场:委托共享 daemon(与 chat 同宿主,统一并发/监控)',
19
+ create: (ctx) => new DaemonBackend({
20
+ backend: 'claude',
34
21
  sessionName: ctx.sessionName,
35
22
  cwd: ctx.cwd,
36
23
  project: ctx.project,
37
24
  resumeSessionId: ctx.resumeSessionId,
38
25
  extraEnv: ctx.extraEnv,
39
- provider: {
40
- providerId,
41
- model: ctx.modelName,
42
- transport,
43
- ...(ctx.providerBaseUrl ? { baseUrl: ctx.providerBaseUrl } : {}),
44
- },
45
- });
26
+ }),
46
27
  },
47
- },
48
- {
49
- id: 'openai-sdk',
50
- summary: '进程内 @openai/agents SDK',
51
- create: (ctx) => new OpenAiAgentBackend({
52
- model: ctx.makeModel(),
53
- cwd: ctx.cwd,
54
- project: ctx.project,
55
- sessionFile: ctx.sessionFile,
56
- }),
57
- },
58
- {
59
- id: 'claude-sdk',
60
- summary: '进程内 claude-agent-sdk',
61
- create: (ctx) => new ClaudeSdkBackend({ model: ctx.modelName, cwd: ctx.cwd, project: ctx.project }),
62
- },
63
- ];
28
+ {
29
+ id: 'openai-daemon',
30
+ summary: 'openai/codex 走共享 daemon;provider 传输按 providerId 推导',
31
+ create: (ctx) => {
32
+ const providerId = ctx.providerId ?? 'official';
33
+ const transport = ctx.providerTransport ??
34
+ (providerId === 'codex'
35
+ ? 'codex'
36
+ : providerId === 'official'
37
+ ? 'responses'
38
+ : 'chat_completions');
39
+ return new DaemonBackend({
40
+ backend: 'openai',
41
+ sessionName: ctx.sessionName,
42
+ cwd: ctx.cwd,
43
+ project: ctx.project,
44
+ resumeSessionId: ctx.resumeSessionId,
45
+ extraEnv: ctx.extraEnv,
46
+ provider: {
47
+ providerId,
48
+ model: ctx.modelName,
49
+ transport,
50
+ ...(ctx.providerBaseUrl ? { baseUrl: ctx.providerBaseUrl } : {}),
51
+ },
52
+ });
53
+ },
54
+ },
55
+ {
56
+ id: 'openai-sdk',
57
+ summary: '进程内 @openai/agents SDK',
58
+ create: (ctx) => new OpenAiAgentBackend({
59
+ model: ctx.makeModel(),
60
+ cwd: ctx.cwd,
61
+ project: ctx.project,
62
+ sessionFile: ctx.sessionFile,
63
+ }),
64
+ },
65
+ {
66
+ id: 'claude-sdk',
67
+ summary: '进程内 claude-agent-sdk',
68
+ create: (bctx) => new ClaudeSdkBackend({
69
+ model: bctx.modelName,
70
+ cwd: bctx.cwd,
71
+ project: bctx.project,
72
+ // 记忆后端可自带一个 claude 插件(hooks 做自动召回)。
73
+ // 🔴 没装记忆插件 ⇒ `[]` ⇒ 不传 plugins 参数 ⇒ 零残留。
74
+ claudePlugins: memoryOf(host)?.workerPlugins() ?? [],
75
+ }),
76
+ },
77
+ ];
78
+ }
64
79
  export const name = 'sps-agents-builtin';
65
80
  export const inject = [AGENTS];
66
81
  export function apply(ctx) {
67
- for (const f of BUILTIN) {
82
+ for (const f of builtins(ctx)) {
68
83
  // effect 作用域:插件卸载时这些后端跟着注销,不会留下"注册着但代码已不在"的条目。
69
84
  ctx.effect(() => ctx[AGENTS].register(f));
70
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/agents-builtin/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/agents-builtin/index.ts"],"names":[],"mappings":"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"}
@@ -89,6 +89,14 @@ export declare abstract class MemorySeam extends Service {
89
89
  project?: string;
90
90
  all?: boolean;
91
91
  }): MemoryMigrateStats;
92
+ /**
93
+ * 要注入 worker 的 Claude Code 插件目录(绝对路径)。默认没有。
94
+ *
95
+ * 🔴 宿主**只拿路径,不解析目录内容** —— hooks.json / .mcp.json 是
96
+ * claude 运行时的格式,和"sps 不解析 claude transcript"同源:
97
+ * 一旦宿主开始读它,换个 claude 版本就要跟着改。
98
+ */
99
+ workerPlugins(): string[];
92
100
  promoteEntry(from: ScopeRef, id: string, to: ScopeRef, opts: {
93
101
  move?: boolean;
94
102
  }): MemoryEntry | null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,IAAI,SAAS,EAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEpF,yCAAyC;AACzC,eAAO,MAAM,MAAM,eAAe,CAAC;AAEnC,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,8BAAsB,UAAW,SAAQ,OAAO;gBAClC,GAAG,EAAE,OAAO;IASxB,wDAAwD;IACxD,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAEzF,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,EAAE;IAClD,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IACjE,QAAQ,CAAC,aAAa,IAAI,QAAQ,EAAE;IAEpC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW;IAChE,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxD;;;OAGG;IACH,OAAO,IAAI,OAAO;IAIlB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAE3C;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAE7B;;;OAGG;IACH;;;OAGG;IACH,YAAY,IAAI,IAAI;IAQpB,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAM;IAE5D,uCAAuC;IACvC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1C,gDAAgD;IAChD,OAAO,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,kBAAkB;IAIzE,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,GAAG,IAAI;CAerG;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,YAAY,EAAE,UAAU,CAAC;KAC1B;CACF;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAKrE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,eAAe,IAAI,SAAS,EAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEpF,yCAAyC;AACzC,eAAO,MAAM,MAAM,eAAe,CAAC;AAEnC,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,8BAAsB,UAAW,SAAQ,OAAO;gBAClC,GAAG,EAAE,OAAO;IASxB,wDAAwD;IACxD,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAEzF,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,EAAE;IAClD,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IACjE,QAAQ,CAAC,aAAa,IAAI,QAAQ,EAAE;IAEpC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,GAAG,WAAW;IAChE,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxD;;;OAGG;IACH,OAAO,IAAI,OAAO;IAIlB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAE3C;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAE7B;;;OAGG;IACH;;;OAGG;IACH,YAAY,IAAI,IAAI;IAQpB,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,EAAE;QAAE,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAM;IAE5D,uCAAuC;IACvC,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1C,gDAAgD;IAChD,OAAO,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,kBAAkB;IAIzE;;;;;;OAMG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,WAAW,GAAG,IAAI;CAerG;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,YAAY,EAAE,UAAU,CAAC;KAC1B;CACF;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAKrE"}
@@ -84,6 +84,16 @@ export class MemorySeam extends Service {
84
84
  migrate(_target) {
85
85
  return {};
86
86
  }
87
+ /**
88
+ * 要注入 worker 的 Claude Code 插件目录(绝对路径)。默认没有。
89
+ *
90
+ * 🔴 宿主**只拿路径,不解析目录内容** —— hooks.json / .mcp.json 是
91
+ * claude 运行时的格式,和"sps 不解析 claude transcript"同源:
92
+ * 一旦宿主开始读它,换个 claude 版本就要跟着改。
93
+ */
94
+ workerPlugins() {
95
+ return [];
96
+ }
87
97
  promoteEntry(from, id, to, opts) {
88
98
  const e = this.readEntry(from, id);
89
99
  if (!e)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EACL,oBAAoB,GAIrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAgB,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG5D,yCAAyC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC;AAQnC,MAAM,OAAgB,UAAW,SAAQ,OAAO;IAC9C,YAAY,GAAY;QACtB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrB,CAAC;IAiBD,+CAA+C;IAE/C;;;OAGG;IACH,OAAO;QACL,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAc,EAAE,GAAW,IAAS,CAAC;IAE9C;;;OAGG;IACH,OAAO,CAAC,IAAc,IAAS,CAAC;IAEhC;;;OAGG;IACH;;;OAGG;IACH,YAAY,KAAU,CAAC;IAEvB,iBAAiB;IACjB,EAAE;IACF,gDAAgD;IAChD,2CAA2C;IAC3C,wBAAwB;IAExB,yBAAyB;IAChB,QAAQ,GAAwC,EAAE,CAAC;IAE5D,uCAAuC;IACvC,EAAE,CAAC,IAAc;QACf,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,gDAAgD;IAChD,OAAO,CAAC,OAA4C;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY,CAAC,IAAc,EAAE,EAAU,EAAE,EAAY,EAAE,IAAwB;QAC7E,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE;YAC/B,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAQD;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,IAAK,GAA0B,CAAC,IAAI,KAAK,oBAAoB;QAAE,OAAO,IAAI,CAAC;IAC3E,MAAM,CAAC,GAAI,GAA6B,CAAC,OAAO,CAAC;IACjD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EACL,oBAAoB,GAIrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAgB,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG5D,yCAAyC;AACzC,MAAM,CAAC,MAAM,MAAM,GAAG,YAAY,CAAC;AAQnC,MAAM,OAAgB,UAAW,SAAQ,OAAO;IAC9C,YAAY,GAAY;QACtB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrB,CAAC;IAiBD,+CAA+C;IAE/C;;;OAGG;IACH,OAAO;QACL,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAc,EAAE,GAAW,IAAS,CAAC;IAE9C;;;OAGG;IACH,OAAO,CAAC,IAAc,IAAS,CAAC;IAEhC;;;OAGG;IACH;;;OAGG;IACH,YAAY,KAAU,CAAC;IAEvB,iBAAiB;IACjB,EAAE;IACF,gDAAgD;IAChD,2CAA2C;IAC3C,wBAAwB;IAExB,yBAAyB;IAChB,QAAQ,GAAwC,EAAE,CAAC;IAE5D,uCAAuC;IACvC,EAAE,CAAC,IAAc;QACf,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,gDAAgD;IAChD,OAAO,CAAC,OAA4C;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;OAMG;IACH,aAAa;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,YAAY,CAAC,IAAc,EAAE,EAAU,EAAE,EAAY,EAAE,IAAwB;QAC7E,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE;YAC/B,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7C,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAQD;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,IAAK,GAA0B,CAAC,IAAI,KAAK,oBAAoB;QAAE,OAAO,IAAI,CAAC;IAC3E,MAAM,CAAC,GAAI,GAA6B,CAAC,OAAO,CAAC;IACjD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9D,CAAC"}
@@ -13,6 +13,11 @@
13
13
  * 而不声明 inject 直接读未注册的服务 ⇒ 返回 `undefined`,不抛错(实测)。
14
14
  * ⇒ 可选能力只能走"运行时探测",这个文件就是那道统一的探测口。
15
15
  *
16
+ * 🔴 **要惰性读,别在 apply 里读一次存起来。** 可选能力不声明 inject,
17
+ * 而 Cordis 不保证两个无依赖关系的插件谁先装 —— apply 时记忆可能还没到。
18
+ * 正确做法是在**真正要用的那一刻**调 `memoryOf()`(如后端工厂的 `create` 里),
19
+ * 那时装配早已完成。
20
+ *
16
21
  * 🔴 **别在调用点各写各的判断** —— 那是"靠每个消费方记得",本仓为这种形状
17
22
  * 付过多次代价。要么走 `memoryOf()` 拿到 null 后显式处理,
18
23
  * 要么走 `withMemory()` 表达"没有就跳过"。
@@ -1 +1 @@
1
- {"version":3,"file":"optional.d.ts","sourceRoot":"","sources":["../../../src/seams/memory/optional.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAE9D;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAI3F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE5E"}
1
+ {"version":3,"file":"optional.d.ts","sourceRoot":"","sources":["../../../src/seams/memory/optional.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAQ9D;AAED,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAI3F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE5E"}
@@ -7,7 +7,13 @@ import { buildMemoryInjection } from '../../core/memory2/inject.js';
7
7
  * 需要区分的调用点自己问 `enabled()`。
8
8
  */
9
9
  export function memoryOf(app) {
10
- return app['sps.memory'] ?? null;
10
+ // 🔴 必须走 `reflect.get` —— 直接 `app['sps.memory']` 在**插件的 apply 上下文**里
11
+ // 会抛 `cannot get property "sps.memory" without inject`。
12
+ // (在根 ctx 上读只是返回 undefined,所以只在插件里踩得到:
13
+ // 2026-08-27 实测,单元测试全绿而 agents-builtin 一装就炸。)
14
+ // reflect.get 的原话是 "Read a service from the store without the inject
15
+ // requirement" —— 这正是"可选能力"需要的读法。
16
+ return app.reflect.get('sps.memory') ?? null;
11
17
  }
12
18
  /** 记忆可用(装了 **且** 后端自己没关)时才做事;否则返回 `undefined`。 */
13
19
  export function withMemory(app, fn) {
@@ -1 +1 @@
1
- {"version":3,"file":"optional.js","sourceRoot":"","sources":["../../../src/seams/memory/optional.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAIpE;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAkB;IACzC,OAAQ,GAAyD,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC;AAC1F,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,UAAU,CAAI,GAAkB,EAAE,EAA0B;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAkB,EAAE,IAAgB;IAClE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"optional.js","sourceRoot":"","sources":["../../../src/seams/memory/optional.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAIpE;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAkB;IACzC,qEAAqE;IACrE,2DAA2D;IAC3D,0CAA0C;IAC1C,kDAAkD;IAClD,wEAAwE;IACxE,qCAAqC;IACrC,OAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAA4B,IAAI,IAAI,CAAC;AAC3E,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,UAAU,CAAI,GAAkB,EAAE,EAA0B;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAkB,EAAE,IAAgB;IAClE,OAAO,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACrE,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @module seams/workspace
3
+ * @description **工作区布局 seam** —— 把"哪个目录算一个项目""哪些路径算用户资产"
4
+ * 这两件**宿主知识**暴露给插件。
5
+ *
6
+ * @layer seam
7
+ *
8
+ * 类型:**甲 · 工厂型**(进程里一个实现;布局是部署决定的,不是项目决定的)。
9
+ *
10
+ * 🔴 **为什么它必须在宿主而不是跟着插件走**:
11
+ * 发现判据是三段布局(`t<租户>/<产品>/<项目>`)——那是 sps 自己的工作区约定;
12
+ * 资产声明是产品级的数据。让每个需要遍历产物的插件各带一份,两份必漂,
13
+ * 而漂的症状是**一部分项目静默缺席**(不是报错)。
14
+ * 实测过同族:coral sidecar 用「目录下含 `assets/`」当判据,
15
+ * "只有 docs/、还没有 assets/"的设计师阶段项目整批缺席(163 个里 36 个)。
16
+ *
17
+ * ⚠️ 它**不认识桶**。同步到哪、用什么协议、凭据是什么,全是插件的事。
18
+ * 这里只回答"有哪些项目、哪些文件算用户产物"。
19
+ */
20
+ import type { SpsAssetScope, SpsWorkspaceProject } from '@coralai/sps-plugin-api';
21
+ import { type Context, Service } from '@deepseek-ai/cordis';
22
+ export declare const WORKSPACE = "sps.workspace";
23
+ export declare const category = "\u5DE5\u4F5C\u533A";
24
+ export declare const description = "\u5DE5\u4F5C\u533A\u5E03\u5C40(\u53EA\u8BFB):\u6309\u7EA6\u5B9A\u53D1\u73B0\u9879\u76EE\u3001\u7ED9\u51FA\u6BCF\u4E2A\u4EA7\u54C1\u7684\u7528\u6237\u8D44\u4EA7\u8303\u56F4\u3002";
25
+ export default class WorkspaceSeam extends Service {
26
+ constructor(ctx: Context);
27
+ root(): string;
28
+ discover(): Promise<SpsWorkspaceProject[]>;
29
+ /**
30
+ * ⚠️ 每次现读声明,不缓存 —— 声明改了以后不该等进程重启。
31
+ * 读盘的代价远小于"改了配置没生效"的排错成本。
32
+ */
33
+ assetScope(product: string): SpsAssetScope;
34
+ }
35
+ declare module '@deepseek-ai/cordis' {
36
+ interface Context {
37
+ 'sps.workspace': WorkspaceSeam;
38
+ }
39
+ }
40
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/workspace/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAK5D,eAAO,MAAM,SAAS,kBAAkB,CAAC;AAEzC,eAAO,MAAM,QAAQ,uBAAQ,CAAC;AAC9B,eAAO,MAAM,WAAW,sLAAqC,CAAC;AAE9D,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;gBACpC,GAAG,EAAE,OAAO;IAIxB,IAAI,IAAI,MAAM;IAId,QAAQ,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAI1C;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa;CAI3C;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,aAAa,CAAC;KAChC;CACF"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @module seams/workspace
3
+ * @description **工作区布局 seam** —— 把"哪个目录算一个项目""哪些路径算用户资产"
4
+ * 这两件**宿主知识**暴露给插件。
5
+ *
6
+ * @layer seam
7
+ *
8
+ * 类型:**甲 · 工厂型**(进程里一个实现;布局是部署决定的,不是项目决定的)。
9
+ *
10
+ * 🔴 **为什么它必须在宿主而不是跟着插件走**:
11
+ * 发现判据是三段布局(`t<租户>/<产品>/<项目>`)——那是 sps 自己的工作区约定;
12
+ * 资产声明是产品级的数据。让每个需要遍历产物的插件各带一份,两份必漂,
13
+ * 而漂的症状是**一部分项目静默缺席**(不是报错)。
14
+ * 实测过同族:coral sidecar 用「目录下含 `assets/`」当判据,
15
+ * "只有 docs/、还没有 assets/"的设计师阶段项目整批缺席(163 个里 36 个)。
16
+ *
17
+ * ⚠️ 它**不认识桶**。同步到哪、用什么协议、凭据是什么,全是插件的事。
18
+ * 这里只回答"有哪些项目、哪些文件算用户产物"。
19
+ */
20
+ import { Service } from '@deepseek-ai/cordis';
21
+ import { workspacesRoot } from '../../core/workspacePaths.js';
22
+ import { discoverProjects } from '../../providers/storage/scanWorkspace.js';
23
+ import { readSyncScope, scopeForProduct } from '../../providers/storage/syncScope.js';
24
+ export const WORKSPACE = 'sps.workspace';
25
+ export const category = '工作区';
26
+ export const description = '工作区布局(只读):按约定发现项目、给出每个产品的用户资产范围。';
27
+ export default class WorkspaceSeam extends Service {
28
+ constructor(ctx) {
29
+ super(ctx, WORKSPACE);
30
+ }
31
+ root() {
32
+ return workspacesRoot();
33
+ }
34
+ discover() {
35
+ return discoverProjects(this.root());
36
+ }
37
+ /**
38
+ * ⚠️ 每次现读声明,不缓存 —— 声明改了以后不该等进程重启。
39
+ * 读盘的代价远小于"改了配置没生效"的排错成本。
40
+ */
41
+ assetScope(product) {
42
+ const resolved = scopeForProduct(product, readSyncScope());
43
+ return { include: [...resolved.include], usedDefault: resolved.usedDefault };
44
+ }
45
+ }
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/workspace/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAgB,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAEtF,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;AAEzC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAE9D,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,YAAY,GAAY;QACtB,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,IAAI;QACF,OAAO,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,QAAQ;QACN,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,OAAe;QACxB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC/E,CAAC;CACF"}
@@ -2,7 +2,7 @@
2
2
  title: 命令说明
3
3
  generated: true
4
4
  source: sps --help
5
- version: 0.90.0
5
+ version: 0.90.2
6
6
  ---
7
7
 
8
8
  # 命令说明
@@ -11,7 +11,7 @@ version: 0.90.0
11
11
  > 改命令说明请改命令自己的 help 文本,然后跑 `npm run gen:help`。
12
12
  > 门禁 `check:help` 会在两者不一致时报红。
13
13
 
14
- 当前版本 `0.90.0` 共 **27** 个命令。
14
+ 当前版本 `0.90.2` 共 **27** 个命令。
15
15
 
16
16
  ### `sps agent`
17
17
 
@@ -2,7 +2,7 @@
2
2
  title: 开放 API
3
3
  generated: true
4
4
  source: src/console/routes/*.ts
5
- version: 0.90.0
5
+ version: 0.90.2
6
6
  ---
7
7
 
8
8
  # 开放 API
@@ -10,7 +10,7 @@ version: 0.90.0
10
10
  > ⚠️ **本页由 `scripts/gen-help-api.mjs` 从路由代码扫出,不要手改。**
11
11
  > 门禁 `check:help` 会在代码与本页不一致时报红。
12
12
 
13
- 共 **175** 条路由(其中 110 条尚无说明)。版本 `0.90.0`。
13
+ 共 **170** 条路由(其中 110 条尚无说明)。版本 `0.90.2`。
14
14
 
15
15
  > ℹ️ 口径:这里**逐条列**(同一路径的不同方法算两条)。门禁 `check:api-docs` 报的是
16
16
  > **归一去重后的唯一路径数**,两个数字不相等是正常的 —— 别拿它们互相"对账"。
@@ -299,16 +299,6 @@ version: 0.90.0
299
299
  | `POST` | `/api/skills/sync` | — |
300
300
  | `GET` | `/api/skills/links/:project` | — |
301
301
 
302
- ### /api/storage · storage
303
-
304
- | 方法 | 路径 | 说明 |
305
- |---|---|---|
306
- | `GET` | `/api/storage` | * 当前配置(**脱敏**) |
307
- | `PUT` | `/api/storage` | 整体替换。缺字段即非法 —— 不做"沿用旧值"的合并,理由见模块头。 |
308
- | `GET` | `/api/storage/active` | * 同步路径今天生效吗 —— 给运维/自检用的**一个字段**,免得从三种状态自己推 |
309
- | `GET` | `/api/storage/scope` | * 同步范围声明(**按产品**)。内容由平台写入,sps 只执行 —— * 🔴 这不违反"配置里不放同步什么":那一条禁的是 **sps 把产品知识写死在代码里**, * 而这里是**数据**。反面教材是 coral sidecar 用 |
310
- | `PUT` | `/api/storage/scope` | 整体替换。缺声明的产品走窄兜底(只同步 `assets/`),而**用了兜底这件事会进日志**。 |
311
-
312
302
  ### /api/subagent · subagent
313
303
 
314
304
  | 方法 | 路径 | 说明 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-cli",
3
- "version": "0.90.0",
3
+ "version": "0.90.2",
4
4
  "description": "SPS CLI — AI-driven development pipeline orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -82,7 +82,7 @@
82
82
  "dependencies": {
83
83
  "@anthropic-ai/claude-agent-sdk": "^0.3.196",
84
84
  "@colbymchenry/codegraph": "^1.2.0",
85
- "@coralai/sps-plugin-api": "^0.11.0",
85
+ "@coralai/sps-plugin-api": "^0.13.0",
86
86
  "@deepseek-ai/cordis": "^4.0.1",
87
87
  "@deepseek-ai/cordis-plugin-include": "^1.0.6",
88
88
  "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
@@ -1,21 +0,0 @@
1
- /**
2
- * @module console/routes/storage
3
- * @description 对象存储接入的配置面(节点级)。设计见 `object-storage-and-workspace-sync.md` §2.1。
4
- *
5
- * @layer console
6
- *
7
- * 🔴 **读侧永不回显凭据。** `GET` 只回 `redact()` 的形状 —— 与 `GET /:project/agent` 同一条规矩:
8
- * 读者是消费方,不是密钥的所有者。这条不是洁癖:今天刚清掉 11 个世界可读的 pm2 env dump,
9
- * 它们含活 token 且躺了 9 天。**凭据每多经过一个面,就多一个会被写进日志的地方。**
10
- *
11
- * 🔴 **`PUT` 是整体替换,不是合并。** 合并语义会让"删掉一个字段"变成不可能表达的操作
12
- * (与 `PUT /:project/media-providers` 同一条)。
13
- *
14
- * ⚠️ 本路由把"去哪儿"(`/`)与"同步什么"(`/scope`)**分成两个端点**,不是混在一个配置里。
15
- * "同步什么"是**平台写入的数据**(按产品),sps 一个产品名都不硬编码 ——
16
- * 禁的是 sps 把产品知识写死在**代码**里(coral sidecar 用「含 assets/ 目录」猜产品语义,
17
- * 静默漏掉 36 个设计师阶段项目),不是禁它接受声明。
18
- */
19
- import { Hono } from 'hono';
20
- export declare function createStorageRoute(): Hono;
21
- //# sourceMappingURL=storage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/console/routes/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAc5B,wBAAgB,kBAAkB,IAAI,IAAI,CAiGzC"}
@@ -1,115 +0,0 @@
1
- /**
2
- * @module console/routes/storage
3
- * @description 对象存储接入的配置面(节点级)。设计见 `object-storage-and-workspace-sync.md` §2.1。
4
- *
5
- * @layer console
6
- *
7
- * 🔴 **读侧永不回显凭据。** `GET` 只回 `redact()` 的形状 —— 与 `GET /:project/agent` 同一条规矩:
8
- * 读者是消费方,不是密钥的所有者。这条不是洁癖:今天刚清掉 11 个世界可读的 pm2 env dump,
9
- * 它们含活 token 且躺了 9 天。**凭据每多经过一个面,就多一个会被写进日志的地方。**
10
- *
11
- * 🔴 **`PUT` 是整体替换,不是合并。** 合并语义会让"删掉一个字段"变成不可能表达的操作
12
- * (与 `PUT /:project/media-providers` 同一条)。
13
- *
14
- * ⚠️ 本路由把"去哪儿"(`/`)与"同步什么"(`/scope`)**分成两个端点**,不是混在一个配置里。
15
- * "同步什么"是**平台写入的数据**(按产品),sps 一个产品名都不硬编码 ——
16
- * 禁的是 sps 把产品知识写死在**代码**里(coral sidecar 用「含 assets/ 目录」猜产品语义,
17
- * 静默漏掉 36 个设计师阶段项目),不是禁它接受声明。
18
- */
19
- import { Hono } from 'hono';
20
- import { activeStorageConfig, readStorageConfig, redact, writeStorageConfig, } from '../../providers/storage/storageConfig.js';
21
- import { readSyncScope, writeSyncScope, } from '../../providers/storage/syncScope.js';
22
- export function createStorageRoute() {
23
- const app = new Hono();
24
- /**
25
- * 当前配置(**脱敏**)。
26
- *
27
- * 三种状态必须可区分,别合并成一个 `enabled: false`:
28
- * ```
29
- * configured:false 没配过 ← 引导去配
30
- * configured:true enabled:false 配了但关着 ← 有意关掉,别劝
31
- * configured:true enabled:true 在用
32
- * ```
33
- */
34
- app.get('/', (c) => {
35
- const cfg = readStorageConfig();
36
- if (!cfg)
37
- return c.json({ data: { configured: false } });
38
- return c.json({ data: { configured: true, ...redact(cfg) } });
39
- });
40
- /** 整体替换。缺字段即非法 —— 不做"沿用旧值"的合并,理由见模块头。 */
41
- app.put('/', async (c) => {
42
- const body = (await c.req.json().catch(() => null));
43
- const invalid = (detail) => c.json({ type: 'validation', title: 'invalid storage config', status: 422, detail }, 422);
44
- if (!body || typeof body !== 'object' || Array.isArray(body))
45
- return invalid('body must be an object');
46
- for (const k of ['endpoint', 'bucket', 'accessKey', 'secretKey']) {
47
- if (typeof body[k] !== 'string' || !body[k]?.trim())
48
- return invalid(`${k} required (non-empty string)`);
49
- }
50
- // 端点一律当**不透明**:只认 http/https,不解析、不推断是哪家存储。
51
- // 与 `POST /api/templates/register` 的 URL 判据同一句 —— 挡掉 file:// 之类把它变成本地读写的形态。
52
- let parsed;
53
- try {
54
- parsed = new URL(body.endpoint);
55
- }
56
- catch {
57
- return invalid(`endpoint 不是合法 URL:${body.endpoint}`);
58
- }
59
- if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
60
- return invalid(`endpoint 只支持 http/https,收到 ${parsed.protocol}`);
61
- }
62
- const cfg = {
63
- endpoint: body.endpoint.trim(),
64
- bucket: body.bucket.trim(),
65
- accessKey: body.accessKey.trim(),
66
- secretKey: body.secretKey.trim(),
67
- region: typeof body.region === 'string' && body.region.trim() ? body.region.trim() : 'us-east-1',
68
- pathStyle: body.pathStyle !== false,
69
- // 🔴 默认关:没显式给 true 就是关。缺省被解释成"最宽松"是最危险的缺省。
70
- enabled: body.enabled === true,
71
- };
72
- writeStorageConfig(cfg);
73
- return c.json({ data: { configured: true, ...redact(cfg) } });
74
- });
75
- /**
76
- * 同步路径今天生效吗 —— 给运维/自检用的**一个字段**,免得从三种状态自己推。
77
- * 🔴 它回的是"有没有活配置",**不是**"桶连得上":连通性要真发一次请求才知道,
78
- * 那是另一个动作(见 §2.1 任务 2 的验收),别让这个端点看起来像在报连通性。
79
- */
80
- app.get('/active', (c) => c.json({ data: { active: activeStorageConfig() !== null } }));
81
- /**
82
- * 同步范围声明(**按产品**)。内容由平台写入,sps 只执行 ——
83
- * 🔴 这不违反"配置里不放同步什么":那一条禁的是 **sps 把产品知识写死在代码里**,
84
- * 而这里是**数据**。反面教材是 coral sidecar 用「目录下含 assets/」猜产品语义,
85
- * 静默漏掉 36 个设计师阶段项目。
86
- */
87
- app.get('/scope', (c) => {
88
- const scope = readSyncScope();
89
- return c.json({ data: scope ?? { products: {} }, declared: scope !== null });
90
- });
91
- /** 整体替换。缺声明的产品走窄兜底(只同步 `assets/`),而**用了兜底这件事会进日志**。 */
92
- app.put('/scope', async (c) => {
93
- const body = (await c.req.json().catch(() => null));
94
- const invalid = (detail) => c.json({ type: 'validation', title: 'invalid sync scope', status: 422, detail }, 422);
95
- if (!body || typeof body.products !== 'object' || body.products === null || Array.isArray(body.products)) {
96
- return invalid('products must be an object keyed by product name');
97
- }
98
- const products = {};
99
- for (const [name, v] of Object.entries(body.products)) {
100
- const inc = v?.include;
101
- if (!Array.isArray(inc) || !inc.every((x) => typeof x === 'string' && x.trim())) {
102
- return invalid(`products.${name}.include must be a non-empty string[]`);
103
- }
104
- // 通配不支持:带上了什么没人会去 diff(coral 选具名白名单的理由,实测有效)
105
- const star = inc.find((x) => x.includes('*'));
106
- if (star)
107
- return invalid(`不支持通配:products.${name}.include 里的 ${star}`);
108
- products[name] = { include: inc };
109
- }
110
- writeSyncScope({ products });
111
- return c.json({ data: { products } });
112
- });
113
- return app;
114
- }
115
- //# sourceMappingURL=storage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/console/routes/storage.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- export interface StorageSyncLoopHandle {
2
- stop(): void;
3
- }
4
- /**
5
- * 起循环。**返回 handle 而不是 never** —— daemon 关停时要能停掉它,
6
- * 否则进程退不干净(而"退不干净"的表现是重启时端口/socket 还被占着)。
7
- */
8
- export declare function startStorageSyncLoop(log: (line: string) => void): StorageSyncLoopHandle;
9
- //# sourceMappingURL=storageSyncLoop.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"storageSyncLoop.d.ts","sourceRoot":"","sources":["../../src/daemon/storageSyncLoop.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,qBAAqB;IACpC,IAAI,IAAI,IAAI,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,qBAAqB,CAqCvF"}